This is the entry point for the paper “Measuring the Landscape of Civil War.” In this file, a raw csv file of the events dataset created for the Mau Mau rebellion is loaded and processed.

Load Library

library(MeasuringLandscapeCivilWar)
Loading required package: data.table
data.table 1.10.4.1
  The fastest way to learn (by data.table authors): https://www.datacamp.com/courses/data-analysis-the-data-table-way
  Documentation: ?data.table, example(data.table) and browseVignettes("data.table")
  Release notes, videos and slides: http://r-datatable.com
Loading required package: devtools
Loading required package: textreuse
Loading required package: LSHR
Loading required package: Matrix
Loading required package: rasterVis
Loading required package: raster
Loading required package: sp

Attaching package: ‘raster’

The following object is masked from ‘package:data.table’:

    shift

Loading required package: lattice
Loading required package: latticeExtra
Loading required package: RColorBrewer
Loading required package: ggplot2

Attaching package: ‘ggplot2’

The following object is masked from ‘package:latticeExtra’:

    layer

Loading required package: rgdal
rgdal: version: 1.2-13, (SVN revision 686)
 Geospatial Data Abstraction Library extensions to R successfully loaded
 Loaded GDAL runtime: GDAL 2.1.3, released 2017/20/01
 Path to GDAL shared files: /usr/share/gdal
 Loaded PROJ.4 runtime: Rel. 4.9.3, 15 August 2016, [PJ_VERSION: 493]
 Path to PROJ.4 shared files: (autodetected)
 Linking to sp version: 1.2-5 
Loading required package: maptools
Checking rgeos availability: TRUE
Loading required package: plyr
Loading required package: glue
Loading required package: mosaic
Loading required package: dplyr

Attaching package: ‘dplyr’

The following object is masked from ‘package:glue’:

    collapse

The following objects are masked from ‘package:plyr’:

    arrange, count, desc, failwith, id, mutate, rename, summarise, summarize

The following objects are masked from ‘package:raster’:

    intersect, select, union

The following objects are masked from ‘package:data.table’:

    between, first, last

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union

Loading required package: ggformula

New to ggformula?  Try the tutorials: 
    learnr::run_tutorial("introduction", package = "ggformula")
    learnr::run_tutorial("refining", package = "ggformula")
Loading required package: mosaicData

The 'mosaic' package masks several functions from core packages in order to add 
additional features.  The original behavior of these functions should not be affected by this.

Note: If you use the Matrix package, be sure to load it BEFORE loading mosaic.

Attaching package: ‘mosaic’

The following objects are masked from ‘package:dplyr’:

    count, do, tally

The following object is masked from ‘package:plyr’:

    count

The following object is masked from ‘package:rgdal’:

    project

The following objects are masked from ‘package:raster’:

    mean, quantile, resample

The following object is masked from ‘package:Matrix’:

    mean

The following objects are masked from ‘package:stats’:

    binom.test, cor, cor.test, cov, fivenum, IQR, median, prop.test, quantile, sd, t.test, var

The following objects are masked from ‘package:base’:

    max, mean, min, prod, range, sample, sum

Loading required package: stringr
Loading required package: stringi
Loading required package: lubridate

Attaching package: ‘lubridate’

The following object is masked from ‘package:plyr’:

    here

The following objects are masked from ‘package:data.table’:

    hour, isoweek, mday, minute, month, quarter, second, wday, week, yday, year

The following object is masked from ‘package:base’:

    date

Loading required package: janitor

Attaching package: ‘janitor’

The following object is masked from ‘package:raster’:

    crosstab

Loading required package: digest
Loading required package: tidyverse
Loading tidyverse: tibble
Loading tidyverse: tidyr
Loading tidyverse: readr
Loading tidyverse: purrr
Conflicts with tidy packages ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
arrange():     dplyr, plyr
as.difftime(): lubridate, base
between():     dplyr, data.table
collapse():    dplyr, glue
compact():     purrr, plyr
count():       dplyr, mosaic, plyr
cross():       purrr, mosaic
date():        lubridate, base
do():          dplyr, mosaic
expand():      tidyr, Matrix
extract():     tidyr, raster
failwith():    dplyr, plyr
filter():      dplyr, stats
first():       dplyr, data.table
here():        lubridate, plyr
hour():        lubridate, data.table
id():          dplyr, plyr
intersect():   lubridate, raster, base
isoweek():     lubridate, data.table
lag():         dplyr, stats
last():        dplyr, data.table
layer():       ggplot2, latticeExtra
mday():        lubridate, data.table
minute():      lubridate, data.table
month():       lubridate, data.table
mutate():      dplyr, plyr
quarter():     lubridate, data.table
rename():      dplyr, plyr
second():      lubridate, data.table
select():      dplyr, raster
setdiff():     lubridate, base
summarise():   dplyr, plyr
summarize():   dplyr, plyr
tally():       dplyr, mosaic
tokenize():    readr, textreuse
transpose():   purrr, data.table
union():       lubridate, raster, base
wday():        lubridate, data.table
week():        lubridate, data.table
yday():        lubridate, data.table
year():        lubridate, data.table
Loading required package: knitr
Loading required package: DT
Loading required package: magrittr

Attaching package: ‘magrittr’

The following object is masked from ‘package:purrr’:

    set_names

The following object is masked from ‘package:tidyr’:

    extract

The following object is masked from ‘package:raster’:

    extract

Loading required package: rgeos
rgeos version: 0.3-25, (SVN revision 555)
 GEOS runtime version: 3.6.1-CAPI-1.10.1 r0 
 Linking to sp version: 1.2-5 
 Polygon checking: TRUE 

Loading required package: ggmap
Google Maps API Terms of Service: http://developers.google.com/maps/terms.
Please cite ggmap if you use it: see citation('ggmap') for details.

Attaching package: ‘ggmap’

The following object is masked from ‘package:magrittr’:

    inset

Loading required package: bookdown
Loading required package: stringdist
Loading required package: sf
Linking to GEOS 3.6.1, GDAL 2.1.3, proj.4 4.9.3, lwgeom 2.3.3 r15473
Loading required package: viridis
Loading required package: viridisLite
Loading required package: rvest
Loading required package: xml2

Attaching package: ‘rvest’

The following object is masked from ‘package:purrr’:

    pluck

The following object is masked from ‘package:readr’:

    guess_encoding

Loading required package: re2r
devtools::load_all()
Loading MeasuringLandscapeCivilWar

# global_loads()
knitr::opts_knit$set(progress = TRUE, verbose = TRUE)
knitr::opts_chunk$set(fig.width = 12, fig.height = 8, warning = FALSE, message = FALSE, cache = TRUE)
options(width = 160)
events <- prep_events(fromscratch = F)

Dates

Basic cleaning. Generaly format is DD.MM.YYYY Sometimes multiple days are included by DD1/DD2/MM/YY. Somtimes year is YY or YYYY. -Your plots seem to suggest that there are a number of typos in the dates. All dates should range between 1951-1961.

#p_load(date)
events$event_date_clean <- events$event_date %>%
                           str_replace_all("[[:digit:]]+/", "") %>% #strip off extra day at the front 01/02.12.1950
                           str_replace_all("\\.", "/")          %>% #Convert periods to slashes
                           trimws()                             %>% #trim whitespace
                           str_replace_all("/52", "/1952")      %>% #convert 2 digit years to 4 digit years
                           str_replace_all("/53", "/1953")      %>% #convert 2 digit years to 4 digit years
                           str_replace_all("/54", "/1954")      %>% #convert 2 digit years to 4 digit years
                           str_replace_all("/55", "/1955")      %>% #convert 2 digit years to 4 digit years
                           str_replace_all("/56", "/1956")      %>% #convert 2 digit years to 4 digit years
                           str_replace_all("/19524", "/1954")   %>% #clean typo
                           dmy()                                    #Feed to lubridate
 67 failed to parse.
events %>% filter(is.na(event_date_clean)) %>% dplyr::select(starts_with("event_date")) %>% distinct() %>% print(n=40) #visualize errors
events$event_date_clean_year <- year(events$event_date_clean)
events$event_date_clean_year %>% tabyl() %>% round(3)

How often are event dates missing?

table(events$event_date=="")

FALSE 
 7946 

The documents also have dates, sometimes spanning a period of time. Can use that to nail down missing dates.

(events$document_date_type <- events$document_date %>% 
                             tolower() %>% 
                             mosaic::derivedFactor(
                                          "unknown" = T,
                                          "missing"     = str_detect(.,"obscured|missing|illegible|xx|Document missing"),
                                          "on the"      = str_detect(.,"on the"),
                                          "to"          = str_detect(.," to"),
                                          "for"         = str_detect(.,"For "),
                                          "week"        = str_detect(.,"week"),
                                          "week ending" = str_detect(.,"week ending"),
                                          "period"      = str_detect(.,"period"),
                                          "fortnight"   = str_detect(.,"fortnight"),
                                          "ending"      = str_detect(.,"ending"),
                                          .method = "last",
                                          .default = "unknown"
                            ) 
 ) %>% tabyl() 
events$document_date_clean <- events$document_date %>% tolower() %>% 
                             str_replace_all("Fortnight Ended |period|week ending|for |the |fortnight |ending |week |From |on ","") %>%
                             str_replace_all("[Digits]*th|[Digits]*st|[Digits]*rd|[Digits]*nd","")
events <- events %>% 
         dplyr::select(-one_of("document_date_1","document_date_2")) %>%  #separate will continue to add columns every time its run
                              separate(col=document_date_clean,
                                        into=c("document_date_1","document_date_2"),
                                        sep = " to|to |To | - ", remove=F, extra="drop", fill="right")
Unknown variables: `document_date_1`, `document_date_2`
events$document_date_clean_1 <- events$document_date_1 %>% 
                                 str_replace_all("[[:digit:]]+/", "")   %>% #strip off extra day at the front 01/02.12.1950
                                 str_replace_all("\\.", "/")             %>% #Convert periods to slashes
                                 trimws() %>%                            
                                 dmy()
 2696 failed to parse.
events$document_date_clean_2 <- events$document_date_2 %>% 
                                 str_replace_all("[[:digit:]]+/", "")   %>% #strip off extra day at the front 01/02.12.1950
                                 str_replace_all("\\.", "/")             %>% #Convert periods to slashes
                                 trimws() %>%                            
                                 dmy()    
 400 failed to parse.
events %>% filter(is.na(document_date_clean_1)) %>% dplyr::select(starts_with("document_date")) %>% distinct() %>% print(n=40) #visualize errors
parse_date_time(c("2016", "2016-04"), orders = c("Y", "Ym"))
[1] "2016-01-01 UTC" "2016-04-01 UTC"
parse_date_time(c("2016", "jan-55"), orders = c("Y", "Ym","bY"))
 1 failed to parse.
[1] "2016-01-01 UTC" NA              
parse_date_time("1904-jan", "yb") #ok so there are jan-54 that don't parse, there are 25 march to 11 april 1953, where the second parses but not the first
All formats failed to parse. No formats found.
[1] NA
events$document_date_best_date <- events$document_date_clean_2
condition <- is.na(events$document_date_best_date)
events$document_date_best_date[condition] <- events$document_date_clean_1[condition]
(events$document_date_best_year <- year(events$document_date_best_date)) %>% tabyl() %>% round(3)

Only 666 missing from the document date

Type of Event

Heads up, some of these event types in the codebook don’t exist in the data. If a category has zero results, it’s not a bug, just codebook needs to be updated.

cat("\014")

p_load(car, stringi, stringr, xtable, SnowballC)
events$type_clean <- str_trim(stri_trans_totitle(events$type))
(events$type_clean_agglow <- events$type_clean %>%
  str_trim() %>%
  tolower() %>%
  car::recode("
             'desertion'='desertion';
             'escape'='escape';
             c('abduction','kidnapping','kidnap','kitnap','kindnap')='abduction';
             c('assault','attack','assaulted','assaults','assualt','assult')='assault';
             c('murder','elimination','kidnap / murder','')='murder';
             c('arson','burn')='arson';
             c('slashed','stampede')='cattle slashing';
             'vandalism'='vandalism';
             c('theft','thefts','thet','missing','lost','entry')='theft';
             c('confiscate','sentenced')='punishment';
             c('capture','captured')='rebel capture';
             c('oath','oathing','recruitment','recruited')='oathing';
             c('contact','caontact','contacts','drove off','drive off','drove  off',
              'chased off','broke up oathing','ambush')='contact';
             c('patrol','police and kpr patrol','sweep')='patrol';
             c('screening','sreening')='screening';
             c('type')='unclassified'
             ")) %>%
  tabyl(sort = TRUE) %>%
  adorn_crosstab(digits = 1)

NAs introduced by coercion

Collapse Event Types

(events$type_clean_aggmed <- car::recode(events$type_clean_agglow, "
                                 c('abduction','assault','murder')='physical violence';
                                 c('vandalism','arson','cattle slashing')='property destruction';
                                 c('theft')='theft';
                                 c('contact','screening','sreening','patrol','punishment')='security operations';
                                 c('desertion','escape','unclassified')='unclassified';
                            ")) %>%
  tabyl(sort = TRUE) %>%
  adorn_crosstab(digits = 1)
NAs introduced by coercion
(events$type_clean_agghigh <- recode(events$type_clean_aggmed, "
                                 c('oathing','physical violence','property destruction','theft')='rebel activity';
                                 c('rebel capture','security operations')='government activity';
                            ")) %>%
  tabyl(sort = TRUE) %>%
  adorn_crosstab(digits = 1)
NAs introduced by coercion

Initiator of Event

Collapsed Initators to just Rebels, Government, and Civilians

cat("\014")

initiator_target_master_clean <- "
c('ammunition')= 'ammunition' ;
c('explosives', 'gelignite')= 'explosives' ;
c('arms', 'firearm', 'gun', 'pistol', 'rifle',
'ammunition', 'rifile', 'shotgun', 'verey pistol')= 'firearms' ;
c('axe','scabbard','weapons')= 'other weapons' ;
c('councillor', 'district commissioner', 'district officer', 'forest ranger', 'game ranger', 
'game warden', 'government',
'government employees', 'port authority', 'public works department', 'screening team' , 'do', 
'govrnment', 'wakamba screening team',
'do munuga','african do','dcmeru', 'colonial authorities' ,'govtemployee'
)= 'colonial authorities' ;
c('chief', 'elders', 'headman' , 'chief chostram','chief eliud', 'chief\\'s sentry'
)= 'tribal authorities' ;
c('buildings', 'cattle dip', 'duka', 'farms',
'garage', 'homes','huts', 'hotel', 'land rover', 'lorry', 'market', 'office', 'oxcart', 'property', 
'pump house', 'sawmill', 'shops', 'stores', 
'tractor', 'vehicle', 'windmill' , 'bullock\\'s farm','cattle boma','coffe trees','coffee trees',
'cuthouse','dairy farm','dip','house','household',
'houses','hut','instrument','labour camp post','labour huts','lorries','lucerne sheds','maize shamba',
'milk factory','pig sty','private property',
'property of civilians','shop','store','thika fishing camp','vehicles')= 'private property';
c('cash', 'funds', 'money' , 'conductor\\'s takings'
)= 'cash';
c('banana', 'barley', 'bran', 'cabbage', 'coffee', 'corn', 'cream', 'crops', 'dairy', 'food', 
'fruit', 'grain', 'honey', 'maize', 
'meat', 'milk', 'oats', 'posho', 'potatoes', 'sugar', 'vegetable', 'wheat',
'food','food etc','food store','food stores','foodstuffs','fruits','grains',
'grains+cloth +money','green maize cobs','potato','potato store',
'potatos','skimmed milk','sugar cane','sugar maize','vegetables','vegitable garden',
'vegitables','wheat bags','wheat store','wheet','whisky'
)= 'food';
c('beast', 'cattle', 'cow', 'herd', 'livestock', 'pig', 'sheep', 'steer', 'stock',
'animal', 'bulls','calf','calves','chicken','cows','donkey','goat','goats',
'head of cattle','head of cow','head of sheep','heifer','heifers',
'lamb','live stock','livestock','livestocks','masai herd','milk cow','ox','ox cart',
'oxen','ram','red poll cattle','shee','sheep or ox','steers','stocks'
)= 'livestock';
c('medical supplies', 'medicine', 'm&b tablets', 'medicines')= 'medicine';
c('bags', 'bedding', 'blankets', 'books', 'charcoal', 'cloth', 'clothing', 
'cooking utensils', 'cutlery', 'equipment', 'farm implements', 
'household items','instruments', 'iron', 'pails','petrol', 'provisions',
'oil', 'sacks', 'supplies', 'tarpaulin', 'thatch', 'timber', 
'tobacco', 'tools', 'uniforms', 'wire', 'wireless set', 'whiskey',
'articles','bag','battery','bucket','ciga','cigarettes','clothes',
'clothing etc','cloths','dairy item','dairy record book','goods',
'material','oil+tins','provisionv','railway uniforms','supplies',
'tarpaulian','typewriter','v- drive belts', 'gunny bags'
)= 'supplies';
c('church')= 'church';
c('airstrip', 'bridges', 'half built village', 'roads', 'trenches', 'water tank',
'bridge', 'bridge broken', 'bridge damaged', 'infrastructure', 'milt property', 
'miltproperty', 'prison camp','stn damaged'
)= 'infrastructure';
c('school', 'school','school building','school house','school property','schools')= 'school';
c('bg','kg','eg', 'guard','embu guard', 'farm guard', 'forest guard', 'home guard',
'ikandine guard', 'kathanjure guard', 'kijabe guard',
'kikuyu guard', 'masai guard', 'meru guard', 'nandi guard', 'nkubu guard',
'stock guard', 'tigoni guard','tp and eg patrol','hg','tp patrol','home guard patrol',
'm', 'm/g','m/g patrol','g',
'kathanjure hg','k g', 'ng',
'eg patrol', 'hg camp','hg leader','hg patrol','hg post','home','home guard','kg post'
)= 'home guard';
c('arab combat' , 'arab combat unit')= 'arab combat units';
c('asian combat', 'asian combat unit', 'asian combat team', 'second asian combat unit' )= 'asian combat units';
c('3 kar', '4 kar', '5 kar', '6 kar', '7 kar', '23 kar', '26 kar','k.a.r','k.p.r','k.a.r.',
'5th k.a.r','5kar','5 k.a.r','4th kar','kar' ) = 'Kings African Rifles';
c('devonshire regiment','devons', 'field intelligence assistant', 'field intelligence officer',
'fio', 'gloucestershire regiment', 'glosters', 'lancashire fusiliers', 'king\\'s shropshire light infantry',
'royal east kent regiment', 'buffs', 'royal fusiliers', 'royal highland regiment','black watch',
'watch', 'royal inniskilling fusiliers', 'royal irish fusiliers', 'royal northumberland fusiliers',
'rnf','police and military', 'army' , 'lancashire fusilliers', 'sp company 1 royal innisks',
'1 rnf', 'rif', 'ksli', 'inniskillings', 'fia','1 glosters', '1 bw', '1 buffs', 
'\"a\" company 1 royal innisks',
'\"a\" company', 'royal fusilers', 'of devons','of 1 glosters', 'lanc fus', 'fusiliers',
'fio kruger','fios','a co devon','4 platoon support company',
'\"c\" company1 royal innisks','6 platoonsp company 1 royal innisks','1 lf',
'\"c\" company',
'\"d\" company','\"a\"','\"a\" company bw','buffs ambush','d company','d\\' force','devens',
'c company','\"d\" force',
'army officer',
'british army officer',
'british military',
'buffs patrol',
'european officer',
'european soldiers',
'gloster patrol'
)= 'british military';
c('kenya regiment','captain folliott’s team' , 'kr', 'kenreg', 'kenregg','kenya regiment sergeant',
'kenya regt','keniya regiment','kenya regiment private')= 'kenya regiment';
c('captain', 'company', 'military', 'army', 'military property', 'platoon', 'security forces',
'security force', 'coy', 'striking force' ,'sentry',
'military (generic)', 'non commissioned officers', 'patrol', 'sentrie', 'sgt white'
)= 'military (generic)';
c('pseudo gang', 'pseudo team', 'trojan', 'psuedo gangs', 'trojan team' , 'tracker group',
'pseudo teams')= 'psuedo gangs';
c('raf', 'bombers', 'air strike', 'harvards', 'raf lincolns','flying squard')='royal air force';
c('general service unit', 'gsu' )= 'paramilitary';
c('cid')='cid';
c('kenya police', 'kp' , 'kp constables\\' quarters', 'kpa'
)= 'kenya police';
c('kenya police reserve', 'kpr', 'kpr officers', 'reserve police officer', 'rpo' , 
'rpos', 'police and k.p.r')= 'kenya police reserve';
c('constable', 'police', 'polce','policy party')= 'police (generic)';
c('railway police' )= 'railway police';
c('special branch', 'blue doctor team', 'special branch team', 'sb officers' )= 'special branch';
c('githumu police', 'masai special constable', 'tribal police', 'tp' , 'tpeg',
'african constable', 'african costable', 'african special constable', 'tribal police'
)= 'tribal police';
c('tribal police reserve', 'tpr') = 'tribal police reserve';
c('manyatta', 'fishing camp', 'sublocation', 'village', 'camp' , 'villages')= 'communities';
c('detainees', 'prisoner', 'prisoners'
)= 'detainees';
c('bandits', 'food foragers', 'gangs', 'gang', 'kiama kia muingi' , 'kkm', 'komerera' , 'mau mau', 'oath administrator', 'passive wing',
'rebels', 'suspects', 'terrorists','terrorosts','terrorist', 'gunman', 'terorist', 'gunmen',
'resistance group','resistance groups', 'oath administrater','oath administrators','passive wing members','resistance','suspect',
'suspected insurgents','terroist','terroists','terrost') = 'suspected insurgents';
c('africans', 'children', 'civilian','civilians', 'driver', 'employees', 'evangelist', 
'family', 'farm boys', 'girls', 'informer',
'kikuyu', 'laborour', 'loyalist', 'masai', 'men', 'mission staff', 'owner', 'passengers',
'people',  'tugen tribesmen' , 'stranger', 'sikh',
'herd boys', 'isiolo game scouts', 'farm labour', 'farmer', 'european', 'employer',
'employee', 'civilan','shopkeeper' , 'students', 'teachers',
'turkana', 'vigilantes', 'women', 'workers','villagers',  'labour', 'local labour',
'kikuyus', 'embu', 'tiriki houseboy', 'samburu', 'manager', 'woman',
'vetofficer', 'mrhiggins', 'masai party','kuria tribesmen','manager of akira estates',
'kuria tribesmen','chstephen','african',
'catholic misson staff', 'african staff', 'asian women', 'bus conductor', 'child',
'civilian(food carriers)', 'civilian(schoolmaster)', 'civilians',
'civilion', 'committee', 'committee member',  'courier','elder','embu tractor driver',
'employees of club','engine boy','girl','golf club staff','his own hut',
'hotel keeper','houseboy','illegal residents','indian','interpreter','kem','kikiyu',
'kikuyu assessor','kikuyu families','kikuyu houseboy','kikuyu labourer','kikyu',
'kirua village','labour line','labour lines','labourer','labourers',
'laboures','labourline','labours','males','man','maragoli','maragoli labourer',
'masai elders','masai tribesman','members of the thika committee',
'mna section leaders','municipal inspectors','non kikuyu employees','person',
'prostitutes','purke masai','pwd employee','railway employees',
'school master','school teacher','sisters committee','somali','staff','strangers',
'taxi drivers','teacher','treasurers',
'headman\\'s son','norton traill\\'s labour','gordon\\'s labour', 'food carriers'
) = 'civilians';
c('')=NA
"
regex <- "\\.|patrol|[1-9]\\s*rd|[1-9]\\s*th" # with regex start trying to get more of these to automatically map instead of generating lots of hand codings
events$initiator_clean <- events$initiator %>% str_trim() %>% gsub(regex, "", .)
events <- events %>%
  dplyr::select(-one_of("initiator_clean_1", "initiator_clean_2", "initiator_clean_3")) %>% # separate will continue to add columns every time its run
  separate(
    col = initiator_clean,
    into = c("initiator_clean_1", "initiator_clean_2", "initiator_clean_3"),
    sep = "and|\\\\|/|\\&|,", remove = F, extra = "drop", fill = "right"
  )
events <- events %>%
  mutate_at(vars(starts_with("initiator_clean_")), funs(gsub(".*police.*", "police", .))) %>%
  mutate_at(vars(starts_with("initiator_clean_")), funs(gsub(".*guard.*", "guard", .))) %>%
  mutate_at(vars(starts_with("initiator_clean_")), funs(gsub(".*terror.*|.*mau mau.*|.*gang.*", "terrorist", .))) %>%
  mutate_at(vars(starts_with("initiator_clean_")), funs(gsub(".*kpr.*|.*k p r.*", "kpr", .))) %>%
  mutate_at(vars(starts_with("initiator_clean_")), funs(gsub(".*kar.*|.*k a r.*", "kar", .))) %>%
  mutate_at(vars(starts_with("initiator_clean_")), funs(gsub(".*coy.*", "coy", .))) %>%
  mutate_at(vars(starts_with("initiator_clean_")), funs(gsub(".*gsu.*", "gsu", .))) %>%
  mutate_at(vars(starts_with("initiator_clean_")), funs(gsub(".*watch.*", "watch", .))) %>%
  mutate_at(vars(starts_with("initiator_clean_")), funs(trimws(.)))
events <- events %>%
  mutate(initiator_clean_1_agglow = recode(initiator_clean_1, initiator_target_master_clean)) %>%
  mutate(initiator_clean_2_agglow = recode(initiator_clean_2, initiator_target_master_clean)) %>%
  mutate(initiator_clean_3_agglow = recode(initiator_clean_3, initiator_target_master_clean))

NAs introduced by coercionNAs introduced by coercionNAs introduced by coercion

# sort(table(events$initiator_clean_1_agglow))
lowlevelagg <- c(
  "arab combat units", "cid", "psuedo gangs", "asian combat units", "special branch",
  "tribal authorities", "tribal police reserve", "royal air force",
  "paramilitary", "kenya regiment", "tribal police", "kenya police reserve", "kenya police",
  "british military", "civilians", "Kings African Rifles", "military (generic)", "police (generic)",
  "railway police", "home guard", "colonial authorities", "suspected insurgents"
)
# events <- events %>%
# mutate(initiator_clean_1_agglow=ifelse(initiator_clean_1_agglow  %in% lowlevelagg & !is.na(initiator_clean_1_agglow),initiator_clean_1_agglow, "uncategorized")) %>% mutate(initiator_clean_2_agglow=ifelse(initiator_clean_2_agglow  %in% lowlevelagg & !is.na(initiator_clean_2_agglow),initiator_clean_2_agglow, "uncategorized")) %>% mutate(initiator_clean_3_agglow=ifelse(initiator_clean_3_agglow  %in% lowlevelagg & !is.na(initiator_clean_3_agglow),initiator_clean_3_agglow, "uncategorized"))
# table(events$initiator_clean_1_agglow, useNA="always")

events[, c("initiator_clean_1_aggmed", "initiator_clean_2_aggmed", "initiator_clean_3_aggmed")] <-
  events[, c("initiator_clean_1_agglow", "initiator_clean_2_agglow", "initiator_clean_3_agglow")]
events <- events %>%
  mutate_at(
    vars(starts_with("initiator_clean_1_aggmed|initiator_clean_2_aggmed|initiator_clean_3_aggmed")),
    .funs = funs(car::recode("
     c('cid','kenya police reserve','kenya police','police (generic)','railway police','special branch',
'tribal police','tribal police reserve') = 'police';
     c('arab combat units','asian combat units','british military','Kings African Rifles',
'kenya regiment','military (generic)','psuedo gangs','royal air force') = 'military'; 
     c('colonial authorities', 'tribal authorities')='civil authorities'
          "))
  )

events$initiator_clean_2_aggmed %>%
  tabyl(sort = TRUE) %>%
  adorn_crosstab(digits = 1)

events[, c("initiator_clean_1_agghigh", "initiator_clean_2_agghigh", "initiator_clean_3_agghigh")] <-
  events[, c("initiator_clean_1_aggmed", "initiator_clean_2_aggmed", "initiator_clean_3_aggmed")]
events <- events %>%
  mutate_at(
    vars(starts_with("initiator_clean_1_agghigh|initiator_clean_2_agghigh|initiator_clean_3_agghigh")),
    .funs = funs(car::recode("
                  c('civil authorities', 'home guard', 'military', 'police', 'paramilitary') ='government';
                  c('suspected insurgents') ='rebels';
          "))
  )

events$initiator_clean_3_agghigh %>%
  tabyl(sort = TRUE) %>%
  adorn_crosstab(digits = 1)

Target of Event

regex <- "\\.|patrol|[1-9]\\s*rd|[1-9]\\s*th" # with regex start trying to get more of these to automatically map instead of generating lots of hand codings
events$target_clean <- events$initiator %>% str_trim() %>% tolower() %>% gsub(regex, "", .)
events <- events %>%
  dplyr::select(-one_of("target_clean_1", "target_clean_2", "target_clean_3")) %>% # separate will continue to add columns every time its run
  separate(
    col = initiator_clean,
    into = c("target_clean_1", "target_clean_2", "target_clean_3"),
    sep = "and|\\\\|/|\\&|,", remove = F, extra = "drop", fill = "right"
  )
events <- events %>%
  mutate_at(vars(starts_with("target_clean_")), funs(gsub(".*police.*", "police", .))) %>%
  mutate_at(vars(starts_with("target_clean_")), funs(gsub(".*guard.*", "guard", .))) %>%
  mutate_at(vars(starts_with("target_clean_")), funs(gsub(".*terror.*|.*mau mau.*|.*gang.*", "terrorist", .))) %>%
  mutate_at(vars(starts_with("target_clean_")), funs(gsub(".*kpr.*|.*k p r.*", "kpr", .))) %>%
  mutate_at(vars(starts_with("target_clean_")), funs(gsub(".*kar.*|.*k a r.*", "kar", .))) %>%
  mutate_at(vars(starts_with("target_clean_")), funs(gsub(".*coy.*", "coy", .))) %>%
  mutate_at(vars(starts_with("target_clean_")), funs(gsub(".*gsu.*", "gsu", .))) %>%
  mutate_at(vars(starts_with("target_clean_")), funs(gsub(".*watch.*", "watch", .))) %>%
  mutate_at(vars(starts_with("target_clean_")), funs(trimws(.)))
events <- events %>%
  mutate(target_clean_1_agglow = recode(target_clean_1, initiator_target_master_clean)) %>%
  mutate(target_clean_2_agglow = recode(target_clean_2, initiator_target_master_clean)) %>%
  mutate(target_clean_3_agglow = recode(target_clean_3, initiator_target_master_clean))
NAs introduced by coercionNAs introduced by coercionNAs introduced by coercion
lowlevelagg <- c(
  "church", "kenya police", "medicine", "tribal police reserve", "detainees", "kenya regiment", "other weapons",
  "paramilitary", "ammunition", "communities", "british military", "military (generic)", "tribal authorities", "kenya police reserve", "tribal police",
  "Kings African Rifles", "infrastructure", "school", "cash", "colonial authorities", "police (generic)", "supplies", "firearms", "food", "private property",
  "home guard", "civilians", "livestock", "suspected insurgents"
)
# events <- events %>%
# mutate(target_clean_1_agglow=ifelse(target_clean_1_agglow  %in% lowlevelagg & !is.na(target_clean_1_agglow),target_clean_1_agglow, "uncategorized")) %>% mutate(target_clean_2_agglow=ifelse(target_clean_2_agglow  %in% lowlevelagg & !is.na(target_clean_2_agglow),target_clean_2_agglow, "uncategorized")) %>% mutate(target_clean_3_agglow=ifelse(target_clean_3_agglow  %in% lowlevelagg & !is.na(target_clean_3_agglow),target_clean_3_agglow, "uncategorized"))
events$target_clean_1_agglow %>%
  tabyl(sort = TRUE) %>%
  adorn_crosstab(digits = 1)

events[, c("target_clean_1_aggmed", "target_clean_2_aggmed", "target_clean_3_aggmed")] <-
  events[, c("target_clean_1_agglow", "target_clean_2_agglow", "target_clean_3_agglow")]
events <- events %>%
  mutate_at(
    vars(starts_with("initiator_clean_1_aggmed|initiator_clean_2_aggmed|initiator_clean_3_aggmed")),
    .funs = funs(car::recode(temp, "
     c('cid','kenya police reserve','kenya police','police (generic)','railway police',
'special branch','tribal police','tribal police reserve') = 'police';
     c('arab combat units','asian combat units','british military','Kings African Rifles',
'kenya regiment','military (generic)','psuedo gangs','royal air force') = 'military';
     c('colonial authorities', 'tribal authorities')='civil authorities';
     c('ammunition','firearms','other weapons')='armaments';
     c('cash','food','livestock','medicine','supplies')='provisions';
     c('church','school','infrastructure')='public buildings';
          "))
  )

events$initiator_clean_1_aggmed %>%
  tabyl(sort = TRUE) %>%
  adorn_crosstab(digits = 1)

events[, c("target_clean_1_agghigh", "target_clean_2_agghigh", "target_clean_3_agghigh")] <-
  events[, c("target_clean_1_aggmed", "target_clean_2_aggmed", "target_clean_3_aggmed")]
events <- events %>%
  mutate_at(
    vars(starts_with("target_clean_1_agghigh|target_clean_2_agghigh|target_clean_3_agghigh")),
    .funs = funs(car::recode("
                  c('civil authorities', 'home guard', 'military', 'police', 'paramilitary') ='government';
                  c('suspected insurgents','detainees') ='rebels';
                  c('armaments','private property','provisions','public buildings') ='property';
                  c('communities','communities')='civilians';
          "))
  )

events$target_clean_1_agghigh %>%
  tabyl(sort = TRUE) %>%
  adorn_crosstab(digits = 1)

Count of Initiators

Helper function for recoding

recoderFunc <- function(data, oldvalue, newvalue) {
  # convert any factors to characters
  if (is.factor(data)) data <- as.character(data)
  if (is.factor(oldvalue)) oldvalue <- as.character(oldvalue)
  if (is.factor(newvalue)) newvalue <- as.character(newvalue)
  # create the return vector
  newvec <- data
  # put recoded values into the correct position in the return vector
  for (i in unique(oldvalue)) newvec[data %in% i] <- newvalue[oldvalue %in% i]
  newvec
}
# These numbers are improvised and can be changed
acouple <- 2
afew <- 3
agang <- 6
agang_large <- 12
recodings <- c(
  "100+", "100",
  "??", "",
  "1 bag", "1",
  "1 blanket", "1",
  "1 burnt down", "1",
  "1 civilian", "1",
  "1 cow, 6 sheep", "7",
  "1 cow", "1",
  "1 goat, clothing", "1",
  "1 goat", "1",
  "1 looted", "1",
  "1 looted", "1",
  "1 ox", "1",
  "1 sheep and chickens", "1",
  "1 sheep, some chickens", "1",
  "1 sheep", "1",
  "1 shotgun ,30 rounds", "31",
  "1 shotgun + 10rds", "11",
  "1 steer", "1",
  "1 village, 1 market", "1",
  "1 wounded", "1",
  "1 wrecked", "1",
  "1+", "1",
  "1+3", "4",
  "1+some", "1",
  "10 acres", "10",
  "10 bags", "10",
  "10 cattle", "10",
  "10 sacks", "10",
  "10 to 12", "11",
  "10 to 15", "13",
  "10/14/2013", "",
  "10/15/2013", "",
  "10/20/2013", "",
  "100 lb", "100",
  "100-130", "115",
  "100-150", "125",
  "100+", 100,
  "10000", "",
  "109 cattle", "109",
  "10bags potatoes", "10",
  "11 cattle", "11",
  "11 sheep", "11",
  "112 bore & 20.1.45 &7 rds", "112",
  "12 bags", "12",
  "12 cattle", "12",
  "12 goats", "12",
  "12 to 15", "13",
  "12 to 20", "17",
  "12/14/2013", "",
  "120 cattle", "120",
  "120+1", "121",
  "13 sheep", "13",
  "13-15", "14",
  "1300 worth", "1300",
  "14 cattle", "14",
  "14 goats", "14",
  "14 head", "14",
  "14+", "14",
  "15 - 20", "18",
  "15 cattle", "15",
  "15 to 20", "17",
  "15 to 20", "17",
  "15 to 25", "20",
  "15-20", "17",
  "15+", "15",
  "150-200", "175",
  "150+", "150",
  "151 cattle", "151",
  "17 cattle", "17",
  "172 bags burnt", "172",
  "18 cattle", "18",
  "19 bags", "19",
  "196 rounds", "196",
  "2 bags maize", "2",
  "2 bags", "2",
  "2 bags", "2",
  "2 buckets", "2",
  "2 cattle hamstrung", "2",
  "2 cattle, corn", "3",
  "2 cattle", "2",
  "2 cows", "2",
  "2 debbies", "2",
  "2 goats", "2",
  "2 groups", "2",
  "2 huts burnt", "2",
  "2 sheep", "2",
  "2 watches, cash", "2",
  "2/3/2013", "",
  "2+", "2",
  "20 bags maize, 9 goats, 32 chickens and ducks, cash", "60",
  "20 bags", "20",
  "20 cattle", "20",
  "20 goats", "20",
  "20 sheep", "20",
  "20 to 25", "23",
  "20 to 30", "25",
  "20 to 40", "30",
  "20-25", "23",
  "20-30", "25",
  "20-35", "30",
  "20-50", "35",
  "20/30", "25",
  "20/30", "25",
  "20+", "20",
  "200 yds", "200",
  "200-300", "250",
  "200+", "200",
  "2000 acres", "2000",
  "21 goats", "21",
  "21 head", "21",
  "22 cattle", "22",
  "25 to 30", "28",
  "25-30", "27",
  "25-30", "27",
  "28 killed", "28",
  "28 sheep", "28",
  "3 bags", "3",
  "3 bags", "3",
  "3 bikes", "3",
  "3 cattle", "3",
  "3 cattle", "3",
  "3 goats", "3",
  "3 or 4", "3",
  "3 or 4", "3",
  "3 pangas", "3",
  "3 sheep, 2 calves", "5",
  "3 sheep", "3",
  "3 to 4", "3",
  "3 to 4", "3",
  "3/10/2013", "",
  "3/4/2013", "",
  "3/5/2013", "",
  "3/6/2013", "",
  "3+", "3",
  "3+3+1+2", "9",
  "3+some", "3",
  "30 acres", "30",
  "30 cattle", "30",
  "30 to 40", "35",
  "30-35", "33",
  "30-40", "35",
  "30-50", "40",
  "30+", "30",
  "300-400", "350",
  "300+", "300",
  "35 bags", "35",
  "35 to 40", "37",
  "38 cattle", "38",
  "3or 4", "3",
  "4 bags potatoes", "4",
  "4 bags", "4",
  "4 goats", "4",
  "4 groups", "",
  "4 or 5", "4",
  "4 oxen", "4",
  "4 sheep", "4",
  "4 to 8", "6",
  "4/6/2013", "",
  "40 bag", "40",
  "40 cattle", "40",
  "40 sacks", "40",
  "40 sheep", "40",
  "40 to 50", "45",
  "40/50", "45",
  "400 cattle", "400",
  "4000", "",
  "44 cattle", "44",
  "5 bags", "5",
  "5 calves", "5",
  "5 cattle", "5",
  "5 destroyed", "5",
  "5 goats", "5",
  "5 killed", "5",
  "5 or 6", "5",
  "5 sheep, 1 ox", "6",
  "5 sheep", "5",
  "5 to 6", "5",
  "5/10/2013", "",
  "5/6/2013", "",
  "50 cattle", "50",
  "50 to 60", "55",
  "50-100", "75",
  "50-60", "55",
  "50-75", "62",
  "50+", "50",
  "50+", "50",
  "5000 acres", "5000",
  "519 +", "519",
  "53 detained", "53",
  "54 sheep and goats", "54",
  "56 committee members", "56",
  "6 bag", "6",
  "6 bags", "6",
  "6 cattle", "6",
  "6 cattle", "6",
  "6 goats", "6",
  "6 or 7", "6",
  "6 sheep and goats", "6",
  "6 sheep", "6",
  "6 to 7", "6",
  "6 to 8", "7",
  "6 to 9", "8",
  "6-8 man", "7",
  "6/10/2013", "",
  "6/8/2013", "",
  "60-100", "80",
  "60-70", "65",
  "64 cattle", "64",
  "7 bags", "7",
  "7 cattle", "7",
  "7 sheep", "7",
  "7/10/2013", "",
  "70 bags", "70",
  "70 cattle, sheep", "70",
  "70-100", "85",
  "70000", "",
  "75 rounds", "75",
  "8 bags potatoes", "8",
  "8 cattle", "8",
  "8 cows slashed", "8",
  "8 cows", "8",
  "8 sheep", "8",
  "8 to 10", "9",
  "8/10/2013", "",
  "80 cattle", "80",
  "80-100", "90",
  "84 sheep, 1 cow, 5 chickens", "90",
  "9 cattle", "9",
  "9 sheep", "9",
  "9 to 10", "9",
  "9+9", "18",
  "900(not clear)", "900",
  "all locals", "",
  "all", "",
  "app 5", "5",
  "app. 100", "100",
  "app. 120", "120",
  "armed gang", agang,
  "band", agang,
  "bands", "",
  "cattle slashing", "",
  "clothing", "",
  "considerable quantity", "",
  "fairly large gang", agang_large,
  "few bags", "",
  "few", "",
  "food", "",
  "gang", agang,
  "gangs", agang_large,
  "guards", afew,
  "half village", "",
  "labour", "",
  "large crowd", "",
  "large force", agang_large,
  "large gang", agang_large,
  "large meeting", "",
  "large number", "",
  "large numbers", "",
  "large quantities", "",
  "large quantity", "",
  "large re-oathing ceremony", "",
  "large scale", "",
  "large", agang_large,
  "largish gang", agang_large,
  "local populace", "",
  "many thousand", "2000",
  "mob", "",
  "not given", "",
  "number", "",
  "occupants", "",
  "over 200", "200",
  "party", "",
  "party", agang,
  "patrol", agang,
  "posho", "",
  "potatoes", "",
  "quantity of clothing", "",
  "section", "",
  "several gangs", "agang_large",
  "several", "3",
  "sheep and goats", "",
  "shs 2,300/-", "2300",
  "shs 60/-", "60",
  "shs. 1,000", "1000",
  "shs. 18", "18",
  "shs. 30", "30",
  "small gang", agang,
  "small gangs", "agang",
  "small group", agang,
  "small party", afew,
  "small", agang,
  "some", afew,
  "sufficient food", "",
  "unknown", "",
  "very large gang", "agang_large",
  "villages in ndia, gichugu, embu divisions", "",
  "wives", ""
)
recodings <- matrix(recodings, ncol = 2, byrow = T)
events$initiator_numbers_numeric <- events$initiator_numbers %>% recoderFunc(., recodings[, 1], recodings[, 2]) %>% as.numeric()
number of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthNAs introduced by coercion
events$target_numbers_numeric <- events$target_numbers %>% recoderFunc(., recodings[, 1], recodings[, 2]) %>% as.numeric()
number of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthNAs introduced by coercion
events$affected_count_numeric <- events$affected_count %>% recoderFunc(., recodings[, 1], recodings[, 2]) %>% as.numeric()
number of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthNAs introduced by coercion

Casualties

events[, c(
  "government_killed_clean", "government_wounded_clean", "government_captured_clean",
  "rebels_killed_clean", "rebels_wounded_clean", "rebels_captured_clean",
  "civilians_killed_clean", "civilians_wounded_clean", "civilians_captured_clean"
)] <-
  events[, c(
    "government_killed", "government_wounded", "government_captured",
    "rebels_killed", "rebels_wounded", "rebels_captured",
    "civilians_killed", "civilians_wounded", "civilians_captured"
  )]
events <- events %>% mutate_at(
  .vars = c(
    "government_killed_clean", "government_wounded_clean", "government_captured_clean",
    "rebels_killed_clean", "rebels_wounded_clean", "rebels_captured_clean",
    "civilians_killed_clean", "civilians_wounded_clean", "civilians_captured_clean"
  ),
  funs(as.numeric(car::recode(., " 'Few'='2';'Many'='3';'others'='2';'Sevaral'='3';
                                  'several'='3'; 'Several More'='3'; 'Several others'='3';
                                   'Some'='3';
                                   '100+'='100'; '23 Families'='23'; '28 families'='28'; '30-40'='35';
                                   '50+'='50'; 'Council of elders'='3';
                                  'Council of war'='3'; 'Few'='2'; 'some'='2'; 
                                   'Several'='3';  '4500'='45'; '800'='80'; 'Gang'='3'; 'Majority'='3'; 
                                 ; 'many'='3'  ; 'Several'='3' ; 'Small gang'='3' ;
                                  '6+'='6' ; '10+'='10' ; '3+'='3';
                                 'unKnown'='1'; 'unknown'='1'; 'UnKnown'='1';  'UNKNOWN'='1'; 'Unkown'='1';
                                 'Unknown'='1' ; 'Number'='1';'More'='1'; '10197'='' ; '101'='1' ;
'48'='7' ; '146'='1' ; '122'='1';  '208'='1'; '94'='1' ;
                                 NA=0")))
)

NAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercionNAs introduced by coercion

events <- events %>% mutate_at(.vars = c(
  "government_killed_clean", "government_wounded_clean", "government_captured_clean",
  "rebels_killed_clean", "rebels_wounded_clean", "rebels_captured_clean",
  "civilians_killed_clean", "civilians_wounded_clean", "civilians_captured_clean"
), funs(as.numeric))
events <- events %>%
  mutate(rebels_killedwounded_clean = rebels_killed_clean + rebels_wounded_clean) %>%
  mutate(government_killed_wounded_clean = government_killed_clean + government_wounded_clean) %>%
  mutate(rebels_government_killedwounded_clean = rebels_killed_clean + rebels_wounded_clean) %>%
  mutate(rebels_government_killed_clean = rebels_killed_clean + government_killed_clean) %>%
  mutate(rebels_government_civilians_killed_clean = rebels_killed_clean + government_killed_clean + civilians_killed_clean)
events %>% crosstab(initiator_clean_1_agghigh, type_clean_agghigh) %>% adorn_crosstab(digits = 1)
events %>% crosstab(target_clean_1_agghigh, type_clean_agghigh) %>% adorn_crosstab(digits = 1)
events %>% crosstab(target_clean_1_agghigh, initiator_clean_1_agghigh) %>% adorn_crosstab(digits = 1)

Output Cleaned File

saveRDS(events, "/home/rexdouglass/Dropbox (rex)/Kenya Article Drafts/MeasuringLandscapeCivilWar/inst/extdata/MeasuringLandscapeCivilWar_events_cleaned.Rdata")
LS0tCnRpdGxlOiAiMDEgUHJlcCBFdmVudHMiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKVGhpcyBpcyB0aGUgZW50cnkgcG9pbnQgZm9yIHRoZSBwYXBlciAiTWVhc3VyaW5nIHRoZSBMYW5kc2NhcGUgb2YgQ2l2aWwgV2FyLiIgSW4gdGhpcyBmaWxlLCBhIHJhdyBjc3YgZmlsZSBvZiB0aGUgZXZlbnRzIGRhdGFzZXQgY3JlYXRlZCBmb3IgdGhlIE1hdSBNYXUgcmViZWxsaW9uIGlzIGxvYWRlZCBhbmQgcHJvY2Vzc2VkLgoKCiMgTG9hZCBMaWJyYXJ5CgpgYGB7ciB9CgpsaWJyYXJ5KE1lYXN1cmluZ0xhbmRzY2FwZUNpdmlsV2FyKQpkZXZ0b29sczo6bG9hZF9hbGwoKQojIGdsb2JhbF9sb2FkcygpCgprbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSA4LCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBUUlVFKQpvcHRpb25zKHdpZHRoID0gMTYwKQoKZXZlbnRzIDwtIHByZXBfZXZlbnRzKGZyb21zY3JhdGNoID0gRikKCmBgYAoKIyBEYXRlcwpCYXNpYyBjbGVhbmluZy4gR2VuZXJhbHkgZm9ybWF0IGlzIERELk1NLllZWVkgU29tZXRpbWVzIG11bHRpcGxlIGRheXMgYXJlIGluY2x1ZGVkIGJ5IEREMS9ERDIvTU0vWVkuIFNvbXRpbWVzIHllYXIgaXMgWVkgb3IgWVlZWS4gCi1Zb3VyIHBsb3RzIHNlZW0gdG8gc3VnZ2VzdCB0aGF0IHRoZXJlIGFyZSBhIG51bWJlciBvZiB0eXBvcyBpbiB0aGUgZGF0ZXMuIEFsbCBkYXRlcyBzaG91bGQgcmFuZ2UgYmV0d2VlbiAxOTUxLTE5NjEuCgpgYGB7ciB9CgojcF9sb2FkKGRhdGUpCgpldmVudHMkZXZlbnRfZGF0ZV9jbGVhbiA8LSBldmVudHMkZXZlbnRfZGF0ZSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKCJbWzpkaWdpdDpdXSsvIiwgIiIpICU+JSAjc3RyaXAgb2ZmIGV4dHJhIGRheSBhdCB0aGUgZnJvbnQgMDEvMDIuMTIuMTk1MAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJfcmVwbGFjZV9hbGwoIlxcLiIsICIvIikgICAgICAgICAgJT4lICNDb252ZXJ0IHBlcmlvZHMgdG8gc2xhc2hlcwogICAgICAgICAgICAgICAgICAgICAgICAgICB0cmltd3MoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJT4lICN0cmltIHdoaXRlc3BhY2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKCIvNTIiLCAiLzE5NTIiKSAgICAgICU+JSAjY29udmVydCAyIGRpZ2l0IHllYXJzIHRvIDQgZGlnaXQgeWVhcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKCIvNTMiLCAiLzE5NTMiKSAgICAgICU+JSAjY29udmVydCAyIGRpZ2l0IHllYXJzIHRvIDQgZGlnaXQgeWVhcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKCIvNTQiLCAiLzE5NTQiKSAgICAgICU+JSAjY29udmVydCAyIGRpZ2l0IHllYXJzIHRvIDQgZGlnaXQgeWVhcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKCIvNTUiLCAiLzE5NTUiKSAgICAgICU+JSAjY29udmVydCAyIGRpZ2l0IHllYXJzIHRvIDQgZGlnaXQgeWVhcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKCIvNTYiLCAiLzE5NTYiKSAgICAgICU+JSAjY29udmVydCAyIGRpZ2l0IHllYXJzIHRvIDQgZGlnaXQgeWVhcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKCIvMTk1MjQiLCAiLzE5NTQiKSAgICU+JSAjY2xlYW4gdHlwbwogICAgICAgICAgICAgICAgICAgICAgICAgICBkbXkoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNGZWVkIHRvIGx1YnJpZGF0ZQoKZXZlbnRzICU+JSBmaWx0ZXIoaXMubmEoZXZlbnRfZGF0ZV9jbGVhbikpICU+JSBkcGx5cjo6c2VsZWN0KHN0YXJ0c193aXRoKCJldmVudF9kYXRlIikpICU+JSBkaXN0aW5jdCgpICU+JSBwcmludChuPTQwKSAjdmlzdWFsaXplIGVycm9ycwoKZXZlbnRzJGV2ZW50X2RhdGVfY2xlYW5feWVhciA8LSB5ZWFyKGV2ZW50cyRldmVudF9kYXRlX2NsZWFuKQpldmVudHMkZXZlbnRfZGF0ZV9jbGVhbl95ZWFyICU+JSB0YWJ5bCgpICU+JSByb3VuZCgzKQoKYGBgCgpIb3cgb2Z0ZW4gYXJlIGV2ZW50IGRhdGVzIG1pc3Npbmc/CgpgYGB7ciB9CnRhYmxlKGV2ZW50cyRldmVudF9kYXRlPT0iIikKYGBgCgpUaGUgZG9jdW1lbnRzIGFsc28gaGF2ZSBkYXRlcywgc29tZXRpbWVzIHNwYW5uaW5nIGEgcGVyaW9kIG9mIHRpbWUuIENhbiB1c2UgdGhhdCB0byBuYWlsIGRvd24gbWlzc2luZyBkYXRlcy4KCmBgYHtyIH0KCihldmVudHMkZG9jdW1lbnRfZGF0ZV90eXBlIDwtIGV2ZW50cyRkb2N1bWVudF9kYXRlICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b2xvd2VyKCkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vc2FpYzo6ZGVyaXZlZEZhY3RvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVua25vd24iID0gVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1pc3NpbmciICAgICA9IHN0cl9kZXRlY3QoLiwib2JzY3VyZWR8bWlzc2luZ3xpbGxlZ2libGV8eHh8RG9jdW1lbnQgbWlzc2luZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib24gdGhlIiAgICAgID0gc3RyX2RldGVjdCguLCJvbiB0aGUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRvIiAgICAgICAgICA9IHN0cl9kZXRlY3QoLiwiIHRvIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3IiICAgICAgICAgPSBzdHJfZGV0ZWN0KC4sIkZvciAiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndlZWsiICAgICAgICA9IHN0cl9kZXRlY3QoLiwid2VlayIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2VlayBlbmRpbmciID0gc3RyX2RldGVjdCguLCJ3ZWVrIGVuZGluZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGVyaW9kIiAgICAgID0gc3RyX2RldGVjdCguLCJwZXJpb2QiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvcnRuaWdodCIgICA9IHN0cl9kZXRlY3QoLiwiZm9ydG5pZ2h0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJlbmRpbmciICAgICAgPSBzdHJfZGV0ZWN0KC4sImVuZGluZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWV0aG9kID0gImxhc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZGVmYXVsdCA9ICJ1bmtub3duIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAKICkgJT4lIHRhYnlsKCkgCgoKZXZlbnRzJGRvY3VtZW50X2RhdGVfY2xlYW4gPC0gZXZlbnRzJGRvY3VtZW50X2RhdGUgJT4lIHRvbG93ZXIoKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKCJGb3J0bmlnaHQgRW5kZWQgfHBlcmlvZHx3ZWVrIGVuZGluZ3xmb3IgfHRoZSB8Zm9ydG5pZ2h0IHxlbmRpbmcgfHdlZWsgfEZyb20gfG9uICIsIiIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cl9yZXBsYWNlX2FsbCgiW0RpZ2l0c10qdGh8W0RpZ2l0c10qc3R8W0RpZ2l0c10qcmR8W0RpZ2l0c10qbmQiLCIiKQoKZXZlbnRzIDwtIGV2ZW50cyAlPiUgCiAgICAgICAgIGRwbHlyOjpzZWxlY3QoLW9uZV9vZigiZG9jdW1lbnRfZGF0ZV8xIiwiZG9jdW1lbnRfZGF0ZV8yIikpICU+JSAgI3NlcGFyYXRlIHdpbGwgY29udGludWUgdG8gYWRkIGNvbHVtbnMgZXZlcnkgdGltZSBpdHMgcnVuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcGFyYXRlKGNvbD1kb2N1bWVudF9kYXRlX2NsZWFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50bz1jKCJkb2N1bWVudF9kYXRlXzEiLCJkb2N1bWVudF9kYXRlXzIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIgdG98dG8gfFRvIHwgLSAiLCByZW1vdmU9RiwgZXh0cmE9ImRyb3AiLCBmaWxsPSJyaWdodCIpCgpldmVudHMkZG9jdW1lbnRfZGF0ZV9jbGVhbl8xIDwtIGV2ZW50cyRkb2N1bWVudF9kYXRlXzEgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJfcmVwbGFjZV9hbGwoIltbOmRpZ2l0Ol1dKy8iLCAiIikgICAlPiUgI3N0cmlwIG9mZiBleHRyYSBkYXkgYXQgdGhlIGZyb250IDAxLzAyLjEyLjE5NTAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKCJcXC4iLCAiLyIpICAgICAgICAgICAgICU+JSAjQ29udmVydCBwZXJpb2RzIHRvIHNsYXNoZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJpbXdzKCkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkbXkoKQoKZXZlbnRzJGRvY3VtZW50X2RhdGVfY2xlYW5fMiA8LSBldmVudHMkZG9jdW1lbnRfZGF0ZV8yICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX3JlcGxhY2VfYWxsKCJbWzpkaWdpdDpdXSsvIiwgIiIpICAgJT4lICNzdHJpcCBvZmYgZXh0cmEgZGF5IGF0IHRoZSBmcm9udCAwMS8wMi4xMi4xOTUwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cl9yZXBsYWNlX2FsbCgiXFwuIiwgIi8iKSAgICAgICAgICAgICAlPiUgI0NvbnZlcnQgcGVyaW9kcyB0byBzbGFzaGVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyaW13cygpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG15KCkgICAgCgpldmVudHMgJT4lIGZpbHRlcihpcy5uYShkb2N1bWVudF9kYXRlX2NsZWFuXzEpKSAlPiUgZHBseXI6OnNlbGVjdChzdGFydHNfd2l0aCgiZG9jdW1lbnRfZGF0ZSIpKSAlPiUgZGlzdGluY3QoKSAlPiUgcHJpbnQobj00MCkgI3Zpc3VhbGl6ZSBlcnJvcnMKCnBhcnNlX2RhdGVfdGltZShjKCIyMDE2IiwgIjIwMTYtMDQiKSwgb3JkZXJzID0gYygiWSIsICJZbSIpKQpwYXJzZV9kYXRlX3RpbWUoYygiMjAxNiIsICJqYW4tNTUiKSwgb3JkZXJzID0gYygiWSIsICJZbSIsImJZIikpCgpwYXJzZV9kYXRlX3RpbWUoIjE5MDQtamFuIiwgInliIikgI29rIHNvIHRoZXJlIGFyZSBqYW4tNTQgdGhhdCBkb24ndCBwYXJzZSwgdGhlcmUgYXJlIDI1IG1hcmNoIHRvIDExIGFwcmlsIDE5NTMsIHdoZXJlIHRoZSBzZWNvbmQgcGFyc2VzIGJ1dCBub3QgdGhlIGZpcnN0CgpldmVudHMkZG9jdW1lbnRfZGF0ZV9iZXN0X2RhdGUgPC0gZXZlbnRzJGRvY3VtZW50X2RhdGVfY2xlYW5fMgpjb25kaXRpb24gPC0gaXMubmEoZXZlbnRzJGRvY3VtZW50X2RhdGVfYmVzdF9kYXRlKQpldmVudHMkZG9jdW1lbnRfZGF0ZV9iZXN0X2RhdGVbY29uZGl0aW9uXSA8LSBldmVudHMkZG9jdW1lbnRfZGF0ZV9jbGVhbl8xW2NvbmRpdGlvbl0KKGV2ZW50cyRkb2N1bWVudF9kYXRlX2Jlc3RfeWVhciA8LSB5ZWFyKGV2ZW50cyRkb2N1bWVudF9kYXRlX2Jlc3RfZGF0ZSkpICU+JSB0YWJ5bCgpICU+JSByb3VuZCgzKQoKYGBgCgpPbmx5IDY2NiBtaXNzaW5nIGZyb20gdGhlIGRvY3VtZW50IGRhdGUKCiMgVHlwZSBvZiBFdmVudAoKSGVhZHMgdXAsIHNvbWUgb2YgdGhlc2UgZXZlbnQgdHlwZXMgaW4gdGhlIGNvZGVib29rIGRvbid0IGV4aXN0IGluIHRoZSBkYXRhLiBJZiBhIGNhdGVnb3J5IGhhcyB6ZXJvIHJlc3VsdHMsIGl0J3Mgbm90IGEgYnVnLCBqdXN0IGNvZGVib29rIG5lZWRzIHRvIGJlIHVwZGF0ZWQuCgpgYGB7ciBUeXBlIG9mIEV2ZW50LCByZXN1bHRzPSJhc2lzIn0KCmNhdCgiXDAxNCIpCnBfbG9hZChjYXIsIHN0cmluZ2ksIHN0cmluZ3IsIHh0YWJsZSwgU25vd2JhbGxDKQpldmVudHMkdHlwZV9jbGVhbiA8LSBzdHJfdHJpbShzdHJpX3RyYW5zX3RvdGl0bGUoZXZlbnRzJHR5cGUpKQoKKGV2ZW50cyR0eXBlX2NsZWFuX2FnZ2xvdyA8LSBldmVudHMkdHlwZV9jbGVhbiAlPiUKICBzdHJfdHJpbSgpICU+JQogIHRvbG93ZXIoKSAlPiUKICBjYXI6OnJlY29kZSgiCiAgICAgICAgICAgICAnZGVzZXJ0aW9uJz0nZGVzZXJ0aW9uJzsKICAgICAgICAgICAgICdlc2NhcGUnPSdlc2NhcGUnOwogICAgICAgICAgICAgYygnYWJkdWN0aW9uJywna2lkbmFwcGluZycsJ2tpZG5hcCcsJ2tpdG5hcCcsJ2tpbmRuYXAnKT0nYWJkdWN0aW9uJzsKICAgICAgICAgICAgIGMoJ2Fzc2F1bHQnLCdhdHRhY2snLCdhc3NhdWx0ZWQnLCdhc3NhdWx0cycsJ2Fzc3VhbHQnLCdhc3N1bHQnKT0nYXNzYXVsdCc7CiAgICAgICAgICAgICBjKCdtdXJkZXInLCdlbGltaW5hdGlvbicsJ2tpZG5hcCAvIG11cmRlcicsJycpPSdtdXJkZXInOwogICAgICAgICAgICAgYygnYXJzb24nLCdidXJuJyk9J2Fyc29uJzsKICAgICAgICAgICAgIGMoJ3NsYXNoZWQnLCdzdGFtcGVkZScpPSdjYXR0bGUgc2xhc2hpbmcnOwogICAgICAgICAgICAgJ3ZhbmRhbGlzbSc9J3ZhbmRhbGlzbSc7CiAgICAgICAgICAgICBjKCd0aGVmdCcsJ3RoZWZ0cycsJ3RoZXQnLCdtaXNzaW5nJywnbG9zdCcsJ2VudHJ5Jyk9J3RoZWZ0JzsKICAgICAgICAgICAgIGMoJ2NvbmZpc2NhdGUnLCdzZW50ZW5jZWQnKT0ncHVuaXNobWVudCc7CiAgICAgICAgICAgICBjKCdjYXB0dXJlJywnY2FwdHVyZWQnKT0ncmViZWwgY2FwdHVyZSc7CiAgICAgICAgICAgICBjKCdvYXRoJywnb2F0aGluZycsJ3JlY3J1aXRtZW50JywncmVjcnVpdGVkJyk9J29hdGhpbmcnOwogICAgICAgICAgICAgYygnY29udGFjdCcsJ2Nhb250YWN0JywnY29udGFjdHMnLCdkcm92ZSBvZmYnLCdkcml2ZSBvZmYnLCdkcm92ZSAgb2ZmJywKICAgICAgICAgICAgICAnY2hhc2VkIG9mZicsJ2Jyb2tlIHVwIG9hdGhpbmcnLCdhbWJ1c2gnKT0nY29udGFjdCc7CiAgICAgICAgICAgICBjKCdwYXRyb2wnLCdwb2xpY2UgYW5kIGtwciBwYXRyb2wnLCdzd2VlcCcpPSdwYXRyb2wnOwogICAgICAgICAgICAgYygnc2NyZWVuaW5nJywnc3JlZW5pbmcnKT0nc2NyZWVuaW5nJzsKICAgICAgICAgICAgIGMoJ3R5cGUnKT0ndW5jbGFzc2lmaWVkJwogICAgICAgICAgICAgIikpICU+JQogIHRhYnlsKHNvcnQgPSBUUlVFKSAlPiUKICBhZG9ybl9jcm9zc3RhYihkaWdpdHMgPSAxKQpgYGAKCiMjIENvbGxhcHNlIEV2ZW50IFR5cGVzCgpgYGB7ciBDb2xsYXBzZSBFdmVudCBUeXBlcyBNZWRpdW0sY2FjaGU9VH0KCihldmVudHMkdHlwZV9jbGVhbl9hZ2dtZWQgPC0gY2FyOjpyZWNvZGUoZXZlbnRzJHR5cGVfY2xlYW5fYWdnbG93LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoJ2FiZHVjdGlvbicsJ2Fzc2F1bHQnLCdtdXJkZXInKT0ncGh5c2ljYWwgdmlvbGVuY2UnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCd2YW5kYWxpc20nLCdhcnNvbicsJ2NhdHRsZSBzbGFzaGluZycpPSdwcm9wZXJ0eSBkZXN0cnVjdGlvbic7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoJ3RoZWZ0Jyk9J3RoZWZ0JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygnY29udGFjdCcsJ3NjcmVlbmluZycsJ3NyZWVuaW5nJywncGF0cm9sJywncHVuaXNobWVudCcpPSdzZWN1cml0eSBvcGVyYXRpb25zJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygnZGVzZXJ0aW9uJywnZXNjYXBlJywndW5jbGFzc2lmaWVkJyk9J3VuY2xhc3NpZmllZCc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKSkgJT4lCiAgdGFieWwoc29ydCA9IFRSVUUpICU+JQogIGFkb3JuX2Nyb3NzdGFiKGRpZ2l0cyA9IDEpCmBgYAoKYGBge3IgQ29sbGFwc2UgRXZlbnQgVHlwZXMgSGlnaCxjYWNoZT1UfQoKKGV2ZW50cyR0eXBlX2NsZWFuX2FnZ2hpZ2ggPC0gcmVjb2RlKGV2ZW50cyR0eXBlX2NsZWFuX2FnZ21lZCwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCdvYXRoaW5nJywncGh5c2ljYWwgdmlvbGVuY2UnLCdwcm9wZXJ0eSBkZXN0cnVjdGlvbicsJ3RoZWZ0Jyk9J3JlYmVsIGFjdGl2aXR5JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygncmViZWwgY2FwdHVyZScsJ3NlY3VyaXR5IG9wZXJhdGlvbnMnKT0nZ292ZXJubWVudCBhY3Rpdml0eSc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKSkgJT4lCiAgdGFieWwoc29ydCA9IFRSVUUpICU+JQogIGFkb3JuX2Nyb3NzdGFiKGRpZ2l0cyA9IDEpCmBgYAoKCgoKIyBJbml0aWF0b3Igb2YgRXZlbnQKCkNvbGxhcHNlZCBJbml0YXRvcnMgdG8ganVzdCBSZWJlbHMsIEdvdmVybm1lbnQsIGFuZCBDaXZpbGlhbnMKCmBgYHtyIEluaXRpYXRvciBvZiBFdmVudCwgcmVzdWx0cz0iYXNpcyJ9CgpjYXQoIlwwMTQiKQoKaW5pdGlhdG9yX3RhcmdldF9tYXN0ZXJfY2xlYW4gPC0gIgpjKCdhbW11bml0aW9uJyk9ICdhbW11bml0aW9uJyA7CgpjKCdleHBsb3NpdmVzJywgJ2dlbGlnbml0ZScpPSAnZXhwbG9zaXZlcycgOwoKYygnYXJtcycsICdmaXJlYXJtJywgJ2d1bicsICdwaXN0b2wnLCAncmlmbGUnLAonYW1tdW5pdGlvbicsICdyaWZpbGUnLCAnc2hvdGd1bicsICd2ZXJleSBwaXN0b2wnKT0gJ2ZpcmVhcm1zJyA7CgpjKCdheGUnLCdzY2FiYmFyZCcsJ3dlYXBvbnMnKT0gJ290aGVyIHdlYXBvbnMnIDsKCmMoJ2NvdW5jaWxsb3InLCAnZGlzdHJpY3QgY29tbWlzc2lvbmVyJywgJ2Rpc3RyaWN0IG9mZmljZXInLCAnZm9yZXN0IHJhbmdlcicsICdnYW1lIHJhbmdlcicsIAonZ2FtZSB3YXJkZW4nLCAnZ292ZXJubWVudCcsCidnb3Zlcm5tZW50IGVtcGxveWVlcycsICdwb3J0IGF1dGhvcml0eScsICdwdWJsaWMgd29ya3MgZGVwYXJ0bWVudCcsICdzY3JlZW5pbmcgdGVhbScgLCAnZG8nLCAKJ2dvdnJubWVudCcsICd3YWthbWJhIHNjcmVlbmluZyB0ZWFtJywKJ2RvIG11bnVnYScsJ2FmcmljYW4gZG8nLCdkY21lcnUnLCAnY29sb25pYWwgYXV0aG9yaXRpZXMnICwnZ292dGVtcGxveWVlJwopPSAnY29sb25pYWwgYXV0aG9yaXRpZXMnIDsKCmMoJ2NoaWVmJywgJ2VsZGVycycsICdoZWFkbWFuJyAsICdjaGllZiBjaG9zdHJhbScsJ2NoaWVmIGVsaXVkJywgJ2NoaWVmXFwncyBzZW50cnknCik9ICd0cmliYWwgYXV0aG9yaXRpZXMnIDsKCmMoJ2J1aWxkaW5ncycsICdjYXR0bGUgZGlwJywgJ2R1a2EnLCAnZmFybXMnLAonZ2FyYWdlJywgJ2hvbWVzJywnaHV0cycsICdob3RlbCcsICdsYW5kIHJvdmVyJywgJ2xvcnJ5JywgJ21hcmtldCcsICdvZmZpY2UnLCAnb3hjYXJ0JywgJ3Byb3BlcnR5JywgCidwdW1wIGhvdXNlJywgJ3Nhd21pbGwnLCAnc2hvcHMnLCAnc3RvcmVzJywgCid0cmFjdG9yJywgJ3ZlaGljbGUnLCAnd2luZG1pbGwnICwgJ2J1bGxvY2tcXCdzIGZhcm0nLCdjYXR0bGUgYm9tYScsJ2NvZmZlIHRyZWVzJywnY29mZmVlIHRyZWVzJywKJ2N1dGhvdXNlJywnZGFpcnkgZmFybScsJ2RpcCcsJ2hvdXNlJywnaG91c2Vob2xkJywKJ2hvdXNlcycsJ2h1dCcsJ2luc3RydW1lbnQnLCdsYWJvdXIgY2FtcCBwb3N0JywnbGFib3VyIGh1dHMnLCdsb3JyaWVzJywnbHVjZXJuZSBzaGVkcycsJ21haXplIHNoYW1iYScsCidtaWxrIGZhY3RvcnknLCdwaWcgc3R5JywncHJpdmF0ZSBwcm9wZXJ0eScsCidwcm9wZXJ0eSBvZiBjaXZpbGlhbnMnLCdzaG9wJywnc3RvcmUnLCd0aGlrYSBmaXNoaW5nIGNhbXAnLCd2ZWhpY2xlcycpPSAncHJpdmF0ZSBwcm9wZXJ0eSc7CgpjKCdjYXNoJywgJ2Z1bmRzJywgJ21vbmV5JyAsICdjb25kdWN0b3JcXCdzIHRha2luZ3MnCik9ICdjYXNoJzsKCmMoJ2JhbmFuYScsICdiYXJsZXknLCAnYnJhbicsICdjYWJiYWdlJywgJ2NvZmZlZScsICdjb3JuJywgJ2NyZWFtJywgJ2Nyb3BzJywgJ2RhaXJ5JywgJ2Zvb2QnLCAKJ2ZydWl0JywgJ2dyYWluJywgJ2hvbmV5JywgJ21haXplJywgCidtZWF0JywgJ21pbGsnLCAnb2F0cycsICdwb3NobycsICdwb3RhdG9lcycsICdzdWdhcicsICd2ZWdldGFibGUnLCAnd2hlYXQnLAonZm9vZCcsJ2Zvb2QgZXRjJywnZm9vZCBzdG9yZScsJ2Zvb2Qgc3RvcmVzJywnZm9vZHN0dWZmcycsJ2ZydWl0cycsJ2dyYWlucycsCidncmFpbnMrY2xvdGggK21vbmV5JywnZ3JlZW4gbWFpemUgY29icycsJ3BvdGF0bycsJ3BvdGF0byBzdG9yZScsCidwb3RhdG9zJywnc2tpbW1lZCBtaWxrJywnc3VnYXIgY2FuZScsJ3N1Z2FyIG1haXplJywndmVnZXRhYmxlcycsJ3ZlZ2l0YWJsZSBnYXJkZW4nLAondmVnaXRhYmxlcycsJ3doZWF0IGJhZ3MnLCd3aGVhdCBzdG9yZScsJ3doZWV0Jywnd2hpc2t5JwopPSAnZm9vZCc7CgpjKCdiZWFzdCcsICdjYXR0bGUnLCAnY293JywgJ2hlcmQnLCAnbGl2ZXN0b2NrJywgJ3BpZycsICdzaGVlcCcsICdzdGVlcicsICdzdG9jaycsCidhbmltYWwnLCAnYnVsbHMnLCdjYWxmJywnY2FsdmVzJywnY2hpY2tlbicsJ2Nvd3MnLCdkb25rZXknLCdnb2F0JywnZ29hdHMnLAonaGVhZCBvZiBjYXR0bGUnLCdoZWFkIG9mIGNvdycsJ2hlYWQgb2Ygc2hlZXAnLCdoZWlmZXInLCdoZWlmZXJzJywKJ2xhbWInLCdsaXZlIHN0b2NrJywnbGl2ZXN0b2NrJywnbGl2ZXN0b2NrcycsJ21hc2FpIGhlcmQnLCdtaWxrIGNvdycsJ294Jywnb3ggY2FydCcsCidveGVuJywncmFtJywncmVkIHBvbGwgY2F0dGxlJywnc2hlZScsJ3NoZWVwIG9yIG94Jywnc3RlZXJzJywnc3RvY2tzJwopPSAnbGl2ZXN0b2NrJzsKCmMoJ21lZGljYWwgc3VwcGxpZXMnLCAnbWVkaWNpbmUnLCAnbSZiIHRhYmxldHMnLCAnbWVkaWNpbmVzJyk9ICdtZWRpY2luZSc7CgpjKCdiYWdzJywgJ2JlZGRpbmcnLCAnYmxhbmtldHMnLCAnYm9va3MnLCAnY2hhcmNvYWwnLCAnY2xvdGgnLCAnY2xvdGhpbmcnLCAKJ2Nvb2tpbmcgdXRlbnNpbHMnLCAnY3V0bGVyeScsICdlcXVpcG1lbnQnLCAnZmFybSBpbXBsZW1lbnRzJywgCidob3VzZWhvbGQgaXRlbXMnLCdpbnN0cnVtZW50cycsICdpcm9uJywgJ3BhaWxzJywncGV0cm9sJywgJ3Byb3Zpc2lvbnMnLAonb2lsJywgJ3NhY2tzJywgJ3N1cHBsaWVzJywgJ3RhcnBhdWxpbicsICd0aGF0Y2gnLCAndGltYmVyJywgCid0b2JhY2NvJywgJ3Rvb2xzJywgJ3VuaWZvcm1zJywgJ3dpcmUnLCAnd2lyZWxlc3Mgc2V0JywgJ3doaXNrZXknLAonYXJ0aWNsZXMnLCdiYWcnLCdiYXR0ZXJ5JywnYnVja2V0JywnY2lnYScsJ2NpZ2FyZXR0ZXMnLCdjbG90aGVzJywKJ2Nsb3RoaW5nIGV0YycsJ2Nsb3RocycsJ2RhaXJ5IGl0ZW0nLCdkYWlyeSByZWNvcmQgYm9vaycsJ2dvb2RzJywKJ21hdGVyaWFsJywnb2lsK3RpbnMnLCdwcm92aXNpb252JywncmFpbHdheSB1bmlmb3JtcycsJ3N1cHBsaWVzJywKJ3RhcnBhdWxpYW4nLCd0eXBld3JpdGVyJywndi0gZHJpdmUgYmVsdHMnLCAnZ3VubnkgYmFncycKKT0gJ3N1cHBsaWVzJzsKCmMoJ2NodXJjaCcpPSAnY2h1cmNoJzsKCmMoJ2FpcnN0cmlwJywgJ2JyaWRnZXMnLCAnaGFsZiBidWlsdCB2aWxsYWdlJywgJ3JvYWRzJywgJ3RyZW5jaGVzJywgJ3dhdGVyIHRhbmsnLAonYnJpZGdlJywgJ2JyaWRnZSBicm9rZW4nLCAnYnJpZGdlIGRhbWFnZWQnLCAnaW5mcmFzdHJ1Y3R1cmUnLCAnbWlsdCBwcm9wZXJ0eScsIAonbWlsdHByb3BlcnR5JywgJ3ByaXNvbiBjYW1wJywnc3RuIGRhbWFnZWQnCik9ICdpbmZyYXN0cnVjdHVyZSc7CgpjKCdzY2hvb2wnLCAnc2Nob29sJywnc2Nob29sIGJ1aWxkaW5nJywnc2Nob29sIGhvdXNlJywnc2Nob29sIHByb3BlcnR5Jywnc2Nob29scycpPSAnc2Nob29sJzsKCmMoJ2JnJywna2cnLCdlZycsICdndWFyZCcsJ2VtYnUgZ3VhcmQnLCAnZmFybSBndWFyZCcsICdmb3Jlc3QgZ3VhcmQnLCAnaG9tZSBndWFyZCcsCidpa2FuZGluZSBndWFyZCcsICdrYXRoYW5qdXJlIGd1YXJkJywgJ2tpamFiZSBndWFyZCcsCidraWt1eXUgZ3VhcmQnLCAnbWFzYWkgZ3VhcmQnLCAnbWVydSBndWFyZCcsICduYW5kaSBndWFyZCcsICdua3VidSBndWFyZCcsCidzdG9jayBndWFyZCcsICd0aWdvbmkgZ3VhcmQnLCd0cCBhbmQgZWcgcGF0cm9sJywnaGcnLCd0cCBwYXRyb2wnLCdob21lIGd1YXJkIHBhdHJvbCcsCidtJywgJ20vZycsJ20vZyBwYXRyb2wnLCdnJywKJ2thdGhhbmp1cmUgaGcnLCdrIGcnLCAnbmcnLAonZWcgcGF0cm9sJywgJ2hnIGNhbXAnLCdoZyBsZWFkZXInLCdoZyBwYXRyb2wnLCdoZyBwb3N0JywnaG9tZScsJ2hvbWUgZ3VhcmQnLCdrZyBwb3N0JwopPSAnaG9tZSBndWFyZCc7CgpjKCdhcmFiIGNvbWJhdCcgLCAnYXJhYiBjb21iYXQgdW5pdCcpPSAnYXJhYiBjb21iYXQgdW5pdHMnOwoKYygnYXNpYW4gY29tYmF0JywgJ2FzaWFuIGNvbWJhdCB1bml0JywgJ2FzaWFuIGNvbWJhdCB0ZWFtJywgJ3NlY29uZCBhc2lhbiBjb21iYXQgdW5pdCcgKT0gJ2FzaWFuIGNvbWJhdCB1bml0cyc7CgpjKCczIGthcicsICc0IGthcicsICc1IGthcicsICc2IGthcicsICc3IGthcicsICcyMyBrYXInLCAnMjYga2FyJywnay5hLnInLCdrLnAucicsJ2suYS5yLicsCic1dGggay5hLnInLCc1a2FyJywnNSBrLmEucicsJzR0aCBrYXInLCdrYXInICkgPSAnS2luZ3MgQWZyaWNhbiBSaWZsZXMnOwoKYygnZGV2b25zaGlyZSByZWdpbWVudCcsJ2Rldm9ucycsICdmaWVsZCBpbnRlbGxpZ2VuY2UgYXNzaXN0YW50JywgJ2ZpZWxkIGludGVsbGlnZW5jZSBvZmZpY2VyJywKJ2ZpbycsICdnbG91Y2VzdGVyc2hpcmUgcmVnaW1lbnQnLCAnZ2xvc3RlcnMnLCAnbGFuY2FzaGlyZSBmdXNpbGllcnMnLCAna2luZ1xcJ3Mgc2hyb3BzaGlyZSBsaWdodCBpbmZhbnRyeScsCidyb3lhbCBlYXN0IGtlbnQgcmVnaW1lbnQnLCAnYnVmZnMnLCAncm95YWwgZnVzaWxpZXJzJywgJ3JveWFsIGhpZ2hsYW5kIHJlZ2ltZW50JywnYmxhY2sgd2F0Y2gnLAond2F0Y2gnLCAncm95YWwgaW5uaXNraWxsaW5nIGZ1c2lsaWVycycsICdyb3lhbCBpcmlzaCBmdXNpbGllcnMnLCAncm95YWwgbm9ydGh1bWJlcmxhbmQgZnVzaWxpZXJzJywKJ3JuZicsJ3BvbGljZSBhbmQgbWlsaXRhcnknLCAnYXJteScgLCAnbGFuY2FzaGlyZSBmdXNpbGxpZXJzJywgJ3NwIGNvbXBhbnkgMSByb3lhbCBpbm5pc2tzJywKJzEgcm5mJywgJ3JpZicsICdrc2xpJywgJ2lubmlza2lsbGluZ3MnLCAnZmlhJywnMSBnbG9zdGVycycsICcxIGJ3JywgJzEgYnVmZnMnLCAKJ1wiYVwiIGNvbXBhbnkgMSByb3lhbCBpbm5pc2tzJywKJ1wiYVwiIGNvbXBhbnknLCAncm95YWwgZnVzaWxlcnMnLCAnb2YgZGV2b25zJywnb2YgMSBnbG9zdGVycycsICdsYW5jIGZ1cycsICdmdXNpbGllcnMnLAonZmlvIGtydWdlcicsJ2Zpb3MnLCdhIGNvIGRldm9uJywnNCBwbGF0b29uIHN1cHBvcnQgY29tcGFueScsCidcImNcIiBjb21wYW55MSByb3lhbCBpbm5pc2tzJywnNiBwbGF0b29uc3AgY29tcGFueSAxIHJveWFsIGlubmlza3MnLCcxIGxmJywKJ1wiY1wiIGNvbXBhbnknLAonXCJkXCIgY29tcGFueScsJ1wiYVwiJywnXCJhXCIgY29tcGFueSBidycsJ2J1ZmZzIGFtYnVzaCcsJ2QgY29tcGFueScsJ2RcXCcgZm9yY2UnLCdkZXZlbnMnLAonYyBjb21wYW55JywnXCJkXCIgZm9yY2UnLAonYXJteSBvZmZpY2VyJywKJ2JyaXRpc2ggYXJteSBvZmZpY2VyJywKJ2JyaXRpc2ggbWlsaXRhcnknLAonYnVmZnMgcGF0cm9sJywKJ2V1cm9wZWFuIG9mZmljZXInLAonZXVyb3BlYW4gc29sZGllcnMnLAonZ2xvc3RlciBwYXRyb2wnCik9ICdicml0aXNoIG1pbGl0YXJ5JzsKCgpjKCdrZW55YSByZWdpbWVudCcsJ2NhcHRhaW4gZm9sbGlvdHTigJlzIHRlYW0nICwgJ2tyJywgJ2tlbnJlZycsICdrZW5yZWdnJywna2VueWEgcmVnaW1lbnQgc2VyZ2VhbnQnLAona2VueWEgcmVndCcsJ2tlbml5YSByZWdpbWVudCcsJ2tlbnlhIHJlZ2ltZW50IHByaXZhdGUnKT0gJ2tlbnlhIHJlZ2ltZW50JzsKCmMoJ2NhcHRhaW4nLCAnY29tcGFueScsICdtaWxpdGFyeScsICdhcm15JywgJ21pbGl0YXJ5IHByb3BlcnR5JywgJ3BsYXRvb24nLCAnc2VjdXJpdHkgZm9yY2VzJywKJ3NlY3VyaXR5IGZvcmNlJywgJ2NveScsICdzdHJpa2luZyBmb3JjZScgLCdzZW50cnknLAonbWlsaXRhcnkgKGdlbmVyaWMpJywgJ25vbiBjb21taXNzaW9uZWQgb2ZmaWNlcnMnLCAncGF0cm9sJywgJ3NlbnRyaWUnLCAnc2d0IHdoaXRlJwopPSAnbWlsaXRhcnkgKGdlbmVyaWMpJzsKCmMoJ3BzZXVkbyBnYW5nJywgJ3BzZXVkbyB0ZWFtJywgJ3Ryb2phbicsICdwc3VlZG8gZ2FuZ3MnLCAndHJvamFuIHRlYW0nICwgJ3RyYWNrZXIgZ3JvdXAnLAoncHNldWRvIHRlYW1zJyk9ICdwc3VlZG8gZ2FuZ3MnOwoKYygncmFmJywgJ2JvbWJlcnMnLCAnYWlyIHN0cmlrZScsICdoYXJ2YXJkcycsICdyYWYgbGluY29sbnMnLCdmbHlpbmcgc3F1YXJkJyk9J3JveWFsIGFpciBmb3JjZSc7CgpjKCdnZW5lcmFsIHNlcnZpY2UgdW5pdCcsICdnc3UnICk9ICdwYXJhbWlsaXRhcnknOwoKYygnY2lkJyk9J2NpZCc7CgpjKCdrZW55YSBwb2xpY2UnLCAna3AnICwgJ2twIGNvbnN0YWJsZXNcXCcgcXVhcnRlcnMnLCAna3BhJwopPSAna2VueWEgcG9saWNlJzsKCmMoJ2tlbnlhIHBvbGljZSByZXNlcnZlJywgJ2twcicsICdrcHIgb2ZmaWNlcnMnLCAncmVzZXJ2ZSBwb2xpY2Ugb2ZmaWNlcicsICdycG8nICwgCidycG9zJywgJ3BvbGljZSBhbmQgay5wLnInKT0gJ2tlbnlhIHBvbGljZSByZXNlcnZlJzsKCmMoJ2NvbnN0YWJsZScsICdwb2xpY2UnLCAncG9sY2UnLCdwb2xpY3kgcGFydHknKT0gJ3BvbGljZSAoZ2VuZXJpYyknOwoKYygncmFpbHdheSBwb2xpY2UnICk9ICdyYWlsd2F5IHBvbGljZSc7CgpjKCdzcGVjaWFsIGJyYW5jaCcsICdibHVlIGRvY3RvciB0ZWFtJywgJ3NwZWNpYWwgYnJhbmNoIHRlYW0nLCAnc2Igb2ZmaWNlcnMnICk9ICdzcGVjaWFsIGJyYW5jaCc7CgpjKCdnaXRodW11IHBvbGljZScsICdtYXNhaSBzcGVjaWFsIGNvbnN0YWJsZScsICd0cmliYWwgcG9saWNlJywgJ3RwJyAsICd0cGVnJywKJ2FmcmljYW4gY29uc3RhYmxlJywgJ2FmcmljYW4gY29zdGFibGUnLCAnYWZyaWNhbiBzcGVjaWFsIGNvbnN0YWJsZScsICd0cmliYWwgcG9saWNlJwopPSAndHJpYmFsIHBvbGljZSc7CgpjKCd0cmliYWwgcG9saWNlIHJlc2VydmUnLCAndHByJykgPSAndHJpYmFsIHBvbGljZSByZXNlcnZlJzsKCmMoJ21hbnlhdHRhJywgJ2Zpc2hpbmcgY2FtcCcsICdzdWJsb2NhdGlvbicsICd2aWxsYWdlJywgJ2NhbXAnICwgJ3ZpbGxhZ2VzJyk9ICdjb21tdW5pdGllcyc7CgpjKCdkZXRhaW5lZXMnLCAncHJpc29uZXInLCAncHJpc29uZXJzJwopPSAnZGV0YWluZWVzJzsKCmMoJ2JhbmRpdHMnLCAnZm9vZCBmb3JhZ2VycycsICdnYW5ncycsICdnYW5nJywgJ2tpYW1hIGtpYSBtdWluZ2knICwgJ2trbScsICdrb21lcmVyYScgLCAnbWF1IG1hdScsICdvYXRoIGFkbWluaXN0cmF0b3InLCAncGFzc2l2ZSB3aW5nJywKJ3JlYmVscycsICdzdXNwZWN0cycsICd0ZXJyb3Jpc3RzJywndGVycm9yb3N0cycsJ3RlcnJvcmlzdCcsICdndW5tYW4nLCAndGVyb3Jpc3QnLCAnZ3VubWVuJywKJ3Jlc2lzdGFuY2UgZ3JvdXAnLCdyZXNpc3RhbmNlIGdyb3VwcycsICdvYXRoIGFkbWluaXN0cmF0ZXInLCdvYXRoIGFkbWluaXN0cmF0b3JzJywncGFzc2l2ZSB3aW5nIG1lbWJlcnMnLCdyZXNpc3RhbmNlJywnc3VzcGVjdCcsCidzdXNwZWN0ZWQgaW5zdXJnZW50cycsJ3RlcnJvaXN0JywndGVycm9pc3RzJywndGVycm9zdCcpID0gJ3N1c3BlY3RlZCBpbnN1cmdlbnRzJzsKCmMoJ2FmcmljYW5zJywgJ2NoaWxkcmVuJywgJ2NpdmlsaWFuJywnY2l2aWxpYW5zJywgJ2RyaXZlcicsICdlbXBsb3llZXMnLCAnZXZhbmdlbGlzdCcsIAonZmFtaWx5JywgJ2Zhcm0gYm95cycsICdnaXJscycsICdpbmZvcm1lcicsCidraWt1eXUnLCAnbGFib3JvdXInLCAnbG95YWxpc3QnLCAnbWFzYWknLCAnbWVuJywgJ21pc3Npb24gc3RhZmYnLCAnb3duZXInLCAncGFzc2VuZ2VycycsCidwZW9wbGUnLCAgJ3R1Z2VuIHRyaWJlc21lbicgLCAnc3RyYW5nZXInLCAnc2lraCcsCidoZXJkIGJveXMnLCAnaXNpb2xvIGdhbWUgc2NvdXRzJywgJ2Zhcm0gbGFib3VyJywgJ2Zhcm1lcicsICdldXJvcGVhbicsICdlbXBsb3llcicsCidlbXBsb3llZScsICdjaXZpbGFuJywnc2hvcGtlZXBlcicgLCAnc3R1ZGVudHMnLCAndGVhY2hlcnMnLAondHVya2FuYScsICd2aWdpbGFudGVzJywgJ3dvbWVuJywgJ3dvcmtlcnMnLCd2aWxsYWdlcnMnLCAgJ2xhYm91cicsICdsb2NhbCBsYWJvdXInLAona2lrdXl1cycsICdlbWJ1JywgJ3RpcmlraSBob3VzZWJveScsICdzYW1idXJ1JywgJ21hbmFnZXInLCAnd29tYW4nLAondmV0b2ZmaWNlcicsICdtcmhpZ2dpbnMnLCAnbWFzYWkgcGFydHknLCdrdXJpYSB0cmliZXNtZW4nLCdtYW5hZ2VyIG9mIGFraXJhIGVzdGF0ZXMnLAona3VyaWEgdHJpYmVzbWVuJywnY2hzdGVwaGVuJywnYWZyaWNhbicsCidjYXRob2xpYyBtaXNzb24gc3RhZmYnLCAnYWZyaWNhbiBzdGFmZicsICdhc2lhbiB3b21lbicsICdidXMgY29uZHVjdG9yJywgJ2NoaWxkJywKJ2NpdmlsaWFuKGZvb2QgY2FycmllcnMpJywgJ2NpdmlsaWFuKHNjaG9vbG1hc3RlciknLCAnY2l2aWxpYW5zJywKJ2NpdmlsaW9uJywgJ2NvbW1pdHRlZScsICdjb21taXR0ZWUgbWVtYmVyJywgICdjb3VyaWVyJywnZWxkZXInLCdlbWJ1IHRyYWN0b3IgZHJpdmVyJywKJ2VtcGxveWVlcyBvZiBjbHViJywnZW5naW5lIGJveScsJ2dpcmwnLCdnb2xmIGNsdWIgc3RhZmYnLCdoaXMgb3duIGh1dCcsCidob3RlbCBrZWVwZXInLCdob3VzZWJveScsJ2lsbGVnYWwgcmVzaWRlbnRzJywnaW5kaWFuJywnaW50ZXJwcmV0ZXInLCdrZW0nLCdraWtpeXUnLAona2lrdXl1IGFzc2Vzc29yJywna2lrdXl1IGZhbWlsaWVzJywna2lrdXl1IGhvdXNlYm95Jywna2lrdXl1IGxhYm91cmVyJywna2lreXUnLAona2lydWEgdmlsbGFnZScsJ2xhYm91ciBsaW5lJywnbGFib3VyIGxpbmVzJywnbGFib3VyZXInLCdsYWJvdXJlcnMnLAonbGFib3VyZXMnLCdsYWJvdXJsaW5lJywnbGFib3VycycsJ21hbGVzJywnbWFuJywnbWFyYWdvbGknLCdtYXJhZ29saSBsYWJvdXJlcicsCidtYXNhaSBlbGRlcnMnLCdtYXNhaSB0cmliZXNtYW4nLCdtZW1iZXJzIG9mIHRoZSB0aGlrYSBjb21taXR0ZWUnLAonbW5hIHNlY3Rpb24gbGVhZGVycycsJ211bmljaXBhbCBpbnNwZWN0b3JzJywnbm9uIGtpa3V5dSBlbXBsb3llZXMnLCdwZXJzb24nLAoncHJvc3RpdHV0ZXMnLCdwdXJrZSBtYXNhaScsJ3B3ZCBlbXBsb3llZScsJ3JhaWx3YXkgZW1wbG95ZWVzJywKJ3NjaG9vbCBtYXN0ZXInLCdzY2hvb2wgdGVhY2hlcicsJ3Npc3RlcnMgY29tbWl0dGVlJywnc29tYWxpJywnc3RhZmYnLCdzdHJhbmdlcnMnLAondGF4aSBkcml2ZXJzJywndGVhY2hlcicsJ3RyZWFzdXJlcnMnLAonaGVhZG1hblxcJ3Mgc29uJywnbm9ydG9uIHRyYWlsbFxcJ3MgbGFib3VyJywnZ29yZG9uXFwncyBsYWJvdXInLCAnZm9vZCBjYXJyaWVycycKKSA9ICdjaXZpbGlhbnMnOwoKYygnJyk9TkEKCiIKCnJlZ2V4IDwtICJcXC58cGF0cm9sfFsxLTldXFxzKnJkfFsxLTldXFxzKnRoIiAjIHdpdGggcmVnZXggc3RhcnQgdHJ5aW5nIHRvIGdldCBtb3JlIG9mIHRoZXNlIHRvIGF1dG9tYXRpY2FsbHkgbWFwIGluc3RlYWQgb2YgZ2VuZXJhdGluZyBsb3RzIG9mIGhhbmQgY29kaW5ncwpldmVudHMkaW5pdGlhdG9yX2NsZWFuIDwtIGV2ZW50cyRpbml0aWF0b3IgJT4lIHN0cl90cmltKCkgJT4lIGdzdWIocmVnZXgsICIiLCAuKQoKZXZlbnRzIDwtIGV2ZW50cyAlPiUKICBkcGx5cjo6c2VsZWN0KC1vbmVfb2YoImluaXRpYXRvcl9jbGVhbl8xIiwgImluaXRpYXRvcl9jbGVhbl8yIiwgImluaXRpYXRvcl9jbGVhbl8zIikpICU+JSAjIHNlcGFyYXRlIHdpbGwgY29udGludWUgdG8gYWRkIGNvbHVtbnMgZXZlcnkgdGltZSBpdHMgcnVuCiAgc2VwYXJhdGUoCiAgICBjb2wgPSBpbml0aWF0b3JfY2xlYW4sCiAgICBpbnRvID0gYygiaW5pdGlhdG9yX2NsZWFuXzEiLCAiaW5pdGlhdG9yX2NsZWFuXzIiLCAiaW5pdGlhdG9yX2NsZWFuXzMiKSwKICAgIHNlcCA9ICJhbmR8XFxcXHwvfFxcJnwsIiwgcmVtb3ZlID0gRiwgZXh0cmEgPSAiZHJvcCIsIGZpbGwgPSAicmlnaHQiCiAgKQoKZXZlbnRzIDwtIGV2ZW50cyAlPiUKICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgiaW5pdGlhdG9yX2NsZWFuXyIpKSwgZnVucyhnc3ViKCIuKnBvbGljZS4qIiwgInBvbGljZSIsIC4pKSkgJT4lCiAgbXV0YXRlX2F0KHZhcnMoc3RhcnRzX3dpdGgoImluaXRpYXRvcl9jbGVhbl8iKSksIGZ1bnMoZ3N1YigiLipndWFyZC4qIiwgImd1YXJkIiwgLikpKSAlPiUKICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgiaW5pdGlhdG9yX2NsZWFuXyIpKSwgZnVucyhnc3ViKCIuKnRlcnJvci4qfC4qbWF1IG1hdS4qfC4qZ2FuZy4qIiwgInRlcnJvcmlzdCIsIC4pKSkgJT4lCiAgbXV0YXRlX2F0KHZhcnMoc3RhcnRzX3dpdGgoImluaXRpYXRvcl9jbGVhbl8iKSksIGZ1bnMoZ3N1YigiLiprcHIuKnwuKmsgcCByLioiLCAia3ByIiwgLikpKSAlPiUKICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgiaW5pdGlhdG9yX2NsZWFuXyIpKSwgZnVucyhnc3ViKCIuKmthci4qfC4qayBhIHIuKiIsICJrYXIiLCAuKSkpICU+JQogIG11dGF0ZV9hdCh2YXJzKHN0YXJ0c193aXRoKCJpbml0aWF0b3JfY2xlYW5fIikpLCBmdW5zKGdzdWIoIi4qY295LioiLCAiY295IiwgLikpKSAlPiUKICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgiaW5pdGlhdG9yX2NsZWFuXyIpKSwgZnVucyhnc3ViKCIuKmdzdS4qIiwgImdzdSIsIC4pKSkgJT4lCiAgbXV0YXRlX2F0KHZhcnMoc3RhcnRzX3dpdGgoImluaXRpYXRvcl9jbGVhbl8iKSksIGZ1bnMoZ3N1YigiLip3YXRjaC4qIiwgIndhdGNoIiwgLikpKSAlPiUKICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgiaW5pdGlhdG9yX2NsZWFuXyIpKSwgZnVucyh0cmltd3MoLikpKQoKZXZlbnRzIDwtIGV2ZW50cyAlPiUKICBtdXRhdGUoaW5pdGlhdG9yX2NsZWFuXzFfYWdnbG93ID0gcmVjb2RlKGluaXRpYXRvcl9jbGVhbl8xLCBpbml0aWF0b3JfdGFyZ2V0X21hc3Rlcl9jbGVhbikpICU+JQogIG11dGF0ZShpbml0aWF0b3JfY2xlYW5fMl9hZ2dsb3cgPSByZWNvZGUoaW5pdGlhdG9yX2NsZWFuXzIsIGluaXRpYXRvcl90YXJnZXRfbWFzdGVyX2NsZWFuKSkgJT4lCiAgbXV0YXRlKGluaXRpYXRvcl9jbGVhbl8zX2FnZ2xvdyA9IHJlY29kZShpbml0aWF0b3JfY2xlYW5fMywgaW5pdGlhdG9yX3RhcmdldF9tYXN0ZXJfY2xlYW4pKQoKIyBzb3J0KHRhYmxlKGV2ZW50cyRpbml0aWF0b3JfY2xlYW5fMV9hZ2dsb3cpKQoKbG93bGV2ZWxhZ2cgPC0gYygKICAiYXJhYiBjb21iYXQgdW5pdHMiLCAiY2lkIiwgInBzdWVkbyBnYW5ncyIsICJhc2lhbiBjb21iYXQgdW5pdHMiLCAic3BlY2lhbCBicmFuY2giLAogICJ0cmliYWwgYXV0aG9yaXRpZXMiLCAidHJpYmFsIHBvbGljZSByZXNlcnZlIiwgInJveWFsIGFpciBmb3JjZSIsCiAgInBhcmFtaWxpdGFyeSIsICJrZW55YSByZWdpbWVudCIsICJ0cmliYWwgcG9saWNlIiwgImtlbnlhIHBvbGljZSByZXNlcnZlIiwgImtlbnlhIHBvbGljZSIsCiAgImJyaXRpc2ggbWlsaXRhcnkiLCAiY2l2aWxpYW5zIiwgIktpbmdzIEFmcmljYW4gUmlmbGVzIiwgIm1pbGl0YXJ5IChnZW5lcmljKSIsICJwb2xpY2UgKGdlbmVyaWMpIiwKICAicmFpbHdheSBwb2xpY2UiLCAiaG9tZSBndWFyZCIsICJjb2xvbmlhbCBhdXRob3JpdGllcyIsICJzdXNwZWN0ZWQgaW5zdXJnZW50cyIKKQoKIyBldmVudHMgPC0gZXZlbnRzICU+JQojIG11dGF0ZShpbml0aWF0b3JfY2xlYW5fMV9hZ2dsb3c9aWZlbHNlKGluaXRpYXRvcl9jbGVhbl8xX2FnZ2xvdyAgJWluJSBsb3dsZXZlbGFnZyAmICFpcy5uYShpbml0aWF0b3JfY2xlYW5fMV9hZ2dsb3cpLGluaXRpYXRvcl9jbGVhbl8xX2FnZ2xvdywgInVuY2F0ZWdvcml6ZWQiKSkgJT4lIG11dGF0ZShpbml0aWF0b3JfY2xlYW5fMl9hZ2dsb3c9aWZlbHNlKGluaXRpYXRvcl9jbGVhbl8yX2FnZ2xvdyAgJWluJSBsb3dsZXZlbGFnZyAmICFpcy5uYShpbml0aWF0b3JfY2xlYW5fMl9hZ2dsb3cpLGluaXRpYXRvcl9jbGVhbl8yX2FnZ2xvdywgInVuY2F0ZWdvcml6ZWQiKSkgJT4lIG11dGF0ZShpbml0aWF0b3JfY2xlYW5fM19hZ2dsb3c9aWZlbHNlKGluaXRpYXRvcl9jbGVhbl8zX2FnZ2xvdyAgJWluJSBsb3dsZXZlbGFnZyAmICFpcy5uYShpbml0aWF0b3JfY2xlYW5fM19hZ2dsb3cpLGluaXRpYXRvcl9jbGVhbl8zX2FnZ2xvdywgInVuY2F0ZWdvcml6ZWQiKSkKCiMgdGFibGUoZXZlbnRzJGluaXRpYXRvcl9jbGVhbl8xX2FnZ2xvdywgdXNlTkE9ImFsd2F5cyIpCmBgYAoKYGBge3IgQ29sbGFwc2UgRXZlbnQgSW5pdGF0b3JzIE1lZGl1bSAsY2FjaGU9VH0KCmV2ZW50c1ssIGMoImluaXRpYXRvcl9jbGVhbl8xX2FnZ21lZCIsICJpbml0aWF0b3JfY2xlYW5fMl9hZ2dtZWQiLCAiaW5pdGlhdG9yX2NsZWFuXzNfYWdnbWVkIildIDwtCiAgZXZlbnRzWywgYygiaW5pdGlhdG9yX2NsZWFuXzFfYWdnbG93IiwgImluaXRpYXRvcl9jbGVhbl8yX2FnZ2xvdyIsICJpbml0aWF0b3JfY2xlYW5fM19hZ2dsb3ciKV0KZXZlbnRzIDwtIGV2ZW50cyAlPiUKICBtdXRhdGVfYXQoCiAgICB2YXJzKHN0YXJ0c193aXRoKCJpbml0aWF0b3JfY2xlYW5fMV9hZ2dtZWR8aW5pdGlhdG9yX2NsZWFuXzJfYWdnbWVkfGluaXRpYXRvcl9jbGVhbl8zX2FnZ21lZCIpKSwKICAgIC5mdW5zID0gZnVucyhjYXI6OnJlY29kZSgiCiAgICAgYygnY2lkJywna2VueWEgcG9saWNlIHJlc2VydmUnLCdrZW55YSBwb2xpY2UnLCdwb2xpY2UgKGdlbmVyaWMpJywncmFpbHdheSBwb2xpY2UnLCdzcGVjaWFsIGJyYW5jaCcsCid0cmliYWwgcG9saWNlJywndHJpYmFsIHBvbGljZSByZXNlcnZlJykgPSAncG9saWNlJzsKICAgICBjKCdhcmFiIGNvbWJhdCB1bml0cycsJ2FzaWFuIGNvbWJhdCB1bml0cycsJ2JyaXRpc2ggbWlsaXRhcnknLCdLaW5ncyBBZnJpY2FuIFJpZmxlcycsCidrZW55YSByZWdpbWVudCcsJ21pbGl0YXJ5IChnZW5lcmljKScsJ3BzdWVkbyBnYW5ncycsJ3JveWFsIGFpciBmb3JjZScpID0gJ21pbGl0YXJ5JzsgCiAgICAgYygnY29sb25pYWwgYXV0aG9yaXRpZXMnLCAndHJpYmFsIGF1dGhvcml0aWVzJyk9J2NpdmlsIGF1dGhvcml0aWVzJwogICAgICAgICAgIikpCiAgKQoKZXZlbnRzJGluaXRpYXRvcl9jbGVhbl8yX2FnZ21lZCAlPiUKICB0YWJ5bChzb3J0ID0gVFJVRSkgJT4lCiAgYWRvcm5fY3Jvc3N0YWIoZGlnaXRzID0gMSkKYGBgCgpgYGB7ciBDb2xsYXBzZSBFdmVudCBJbml0YXRvcnMgSGlnaCAsY2FjaGU9VH0KCmV2ZW50c1ssIGMoImluaXRpYXRvcl9jbGVhbl8xX2FnZ2hpZ2giLCAiaW5pdGlhdG9yX2NsZWFuXzJfYWdnaGlnaCIsICJpbml0aWF0b3JfY2xlYW5fM19hZ2doaWdoIildIDwtCiAgZXZlbnRzWywgYygiaW5pdGlhdG9yX2NsZWFuXzFfYWdnbWVkIiwgImluaXRpYXRvcl9jbGVhbl8yX2FnZ21lZCIsICJpbml0aWF0b3JfY2xlYW5fM19hZ2dtZWQiKV0KZXZlbnRzIDwtIGV2ZW50cyAlPiUKICBtdXRhdGVfYXQoCiAgICB2YXJzKHN0YXJ0c193aXRoKCJpbml0aWF0b3JfY2xlYW5fMV9hZ2doaWdofGluaXRpYXRvcl9jbGVhbl8yX2FnZ2hpZ2h8aW5pdGlhdG9yX2NsZWFuXzNfYWdnaGlnaCIpKSwKICAgIC5mdW5zID0gZnVucyhjYXI6OnJlY29kZSgiCiAgICAgICAgICAgICAgICAgIGMoJ2NpdmlsIGF1dGhvcml0aWVzJywgJ2hvbWUgZ3VhcmQnLCAnbWlsaXRhcnknLCAncG9saWNlJywgJ3BhcmFtaWxpdGFyeScpID0nZ292ZXJubWVudCc7CiAgICAgICAgICAgICAgICAgIGMoJ3N1c3BlY3RlZCBpbnN1cmdlbnRzJykgPSdyZWJlbHMnOwogICAgICAgICAgIikpCiAgKQoKZXZlbnRzJGluaXRpYXRvcl9jbGVhbl8zX2FnZ2hpZ2ggJT4lCiAgdGFieWwoc29ydCA9IFRSVUUpICU+JQogIGFkb3JuX2Nyb3NzdGFiKGRpZ2l0cyA9IDEpCmBgYAoKIyBUYXJnZXQgb2YgRXZlbnQKCmBgYHtyIFRhcmdldCBvZiBFdmVudCBMb3csIGNhY2hlPVR9CgpyZWdleCA8LSAiXFwufHBhdHJvbHxbMS05XVxccypyZHxbMS05XVxccyp0aCIgIyB3aXRoIHJlZ2V4IHN0YXJ0IHRyeWluZyB0byBnZXQgbW9yZSBvZiB0aGVzZSB0byBhdXRvbWF0aWNhbGx5IG1hcCBpbnN0ZWFkIG9mIGdlbmVyYXRpbmcgbG90cyBvZiBoYW5kIGNvZGluZ3MKZXZlbnRzJHRhcmdldF9jbGVhbiA8LSBldmVudHMkaW5pdGlhdG9yICU+JSBzdHJfdHJpbSgpICU+JSB0b2xvd2VyKCkgJT4lIGdzdWIocmVnZXgsICIiLCAuKQoKZXZlbnRzIDwtIGV2ZW50cyAlPiUKICBkcGx5cjo6c2VsZWN0KC1vbmVfb2YoInRhcmdldF9jbGVhbl8xIiwgInRhcmdldF9jbGVhbl8yIiwgInRhcmdldF9jbGVhbl8zIikpICU+JSAjIHNlcGFyYXRlIHdpbGwgY29udGludWUgdG8gYWRkIGNvbHVtbnMgZXZlcnkgdGltZSBpdHMgcnVuCiAgc2VwYXJhdGUoCiAgICBjb2wgPSBpbml0aWF0b3JfY2xlYW4sCiAgICBpbnRvID0gYygidGFyZ2V0X2NsZWFuXzEiLCAidGFyZ2V0X2NsZWFuXzIiLCAidGFyZ2V0X2NsZWFuXzMiKSwKICAgIHNlcCA9ICJhbmR8XFxcXHwvfFxcJnwsIiwgcmVtb3ZlID0gRiwgZXh0cmEgPSAiZHJvcCIsIGZpbGwgPSAicmlnaHQiCiAgKQoKZXZlbnRzIDwtIGV2ZW50cyAlPiUKICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgidGFyZ2V0X2NsZWFuXyIpKSwgZnVucyhnc3ViKCIuKnBvbGljZS4qIiwgInBvbGljZSIsIC4pKSkgJT4lCiAgbXV0YXRlX2F0KHZhcnMoc3RhcnRzX3dpdGgoInRhcmdldF9jbGVhbl8iKSksIGZ1bnMoZ3N1YigiLipndWFyZC4qIiwgImd1YXJkIiwgLikpKSAlPiUKICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgidGFyZ2V0X2NsZWFuXyIpKSwgZnVucyhnc3ViKCIuKnRlcnJvci4qfC4qbWF1IG1hdS4qfC4qZ2FuZy4qIiwgInRlcnJvcmlzdCIsIC4pKSkgJT4lCiAgbXV0YXRlX2F0KHZhcnMoc3RhcnRzX3dpdGgoInRhcmdldF9jbGVhbl8iKSksIGZ1bnMoZ3N1YigiLiprcHIuKnwuKmsgcCByLioiLCAia3ByIiwgLikpKSAlPiUKICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgidGFyZ2V0X2NsZWFuXyIpKSwgZnVucyhnc3ViKCIuKmthci4qfC4qayBhIHIuKiIsICJrYXIiLCAuKSkpICU+JQogIG11dGF0ZV9hdCh2YXJzKHN0YXJ0c193aXRoKCJ0YXJnZXRfY2xlYW5fIikpLCBmdW5zKGdzdWIoIi4qY295LioiLCAiY295IiwgLikpKSAlPiUKICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgidGFyZ2V0X2NsZWFuXyIpKSwgZnVucyhnc3ViKCIuKmdzdS4qIiwgImdzdSIsIC4pKSkgJT4lCiAgbXV0YXRlX2F0KHZhcnMoc3RhcnRzX3dpdGgoInRhcmdldF9jbGVhbl8iKSksIGZ1bnMoZ3N1YigiLip3YXRjaC4qIiwgIndhdGNoIiwgLikpKSAlPiUKICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgidGFyZ2V0X2NsZWFuXyIpKSwgZnVucyh0cmltd3MoLikpKQoKZXZlbnRzIDwtIGV2ZW50cyAlPiUKICBtdXRhdGUodGFyZ2V0X2NsZWFuXzFfYWdnbG93ID0gcmVjb2RlKHRhcmdldF9jbGVhbl8xLCBpbml0aWF0b3JfdGFyZ2V0X21hc3Rlcl9jbGVhbikpICU+JQogIG11dGF0ZSh0YXJnZXRfY2xlYW5fMl9hZ2dsb3cgPSByZWNvZGUodGFyZ2V0X2NsZWFuXzIsIGluaXRpYXRvcl90YXJnZXRfbWFzdGVyX2NsZWFuKSkgJT4lCiAgbXV0YXRlKHRhcmdldF9jbGVhbl8zX2FnZ2xvdyA9IHJlY29kZSh0YXJnZXRfY2xlYW5fMywgaW5pdGlhdG9yX3RhcmdldF9tYXN0ZXJfY2xlYW4pKQoKbG93bGV2ZWxhZ2cgPC0gYygKICAiY2h1cmNoIiwgImtlbnlhIHBvbGljZSIsICJtZWRpY2luZSIsICJ0cmliYWwgcG9saWNlIHJlc2VydmUiLCAiZGV0YWluZWVzIiwgImtlbnlhIHJlZ2ltZW50IiwgIm90aGVyIHdlYXBvbnMiLAogICJwYXJhbWlsaXRhcnkiLCAiYW1tdW5pdGlvbiIsICJjb21tdW5pdGllcyIsICJicml0aXNoIG1pbGl0YXJ5IiwgIm1pbGl0YXJ5IChnZW5lcmljKSIsICJ0cmliYWwgYXV0aG9yaXRpZXMiLCAia2VueWEgcG9saWNlIHJlc2VydmUiLCAidHJpYmFsIHBvbGljZSIsCiAgIktpbmdzIEFmcmljYW4gUmlmbGVzIiwgImluZnJhc3RydWN0dXJlIiwgInNjaG9vbCIsICJjYXNoIiwgImNvbG9uaWFsIGF1dGhvcml0aWVzIiwgInBvbGljZSAoZ2VuZXJpYykiLCAic3VwcGxpZXMiLCAiZmlyZWFybXMiLCAiZm9vZCIsICJwcml2YXRlIHByb3BlcnR5IiwKICAiaG9tZSBndWFyZCIsICJjaXZpbGlhbnMiLCAibGl2ZXN0b2NrIiwgInN1c3BlY3RlZCBpbnN1cmdlbnRzIgopCgojIGV2ZW50cyA8LSBldmVudHMgJT4lCiMgbXV0YXRlKHRhcmdldF9jbGVhbl8xX2FnZ2xvdz1pZmVsc2UodGFyZ2V0X2NsZWFuXzFfYWdnbG93ICAlaW4lIGxvd2xldmVsYWdnICYgIWlzLm5hKHRhcmdldF9jbGVhbl8xX2FnZ2xvdyksdGFyZ2V0X2NsZWFuXzFfYWdnbG93LCAidW5jYXRlZ29yaXplZCIpKSAlPiUgbXV0YXRlKHRhcmdldF9jbGVhbl8yX2FnZ2xvdz1pZmVsc2UodGFyZ2V0X2NsZWFuXzJfYWdnbG93ICAlaW4lIGxvd2xldmVsYWdnICYgIWlzLm5hKHRhcmdldF9jbGVhbl8yX2FnZ2xvdyksdGFyZ2V0X2NsZWFuXzJfYWdnbG93LCAidW5jYXRlZ29yaXplZCIpKSAlPiUgbXV0YXRlKHRhcmdldF9jbGVhbl8zX2FnZ2xvdz1pZmVsc2UodGFyZ2V0X2NsZWFuXzNfYWdnbG93ICAlaW4lIGxvd2xldmVsYWdnICYgIWlzLm5hKHRhcmdldF9jbGVhbl8zX2FnZ2xvdyksdGFyZ2V0X2NsZWFuXzNfYWdnbG93LCAidW5jYXRlZ29yaXplZCIpKQoKZXZlbnRzJHRhcmdldF9jbGVhbl8xX2FnZ2xvdyAlPiUKICB0YWJ5bChzb3J0ID0gVFJVRSkgJT4lCiAgYWRvcm5fY3Jvc3N0YWIoZGlnaXRzID0gMSkKYGBgCgoKYGBge3IgQ29sbGFwc2UgRXZlbnQgVGFyZ2V0IE1lZGl1bSAsY2FjaGU9VH0KCmV2ZW50c1ssIGMoInRhcmdldF9jbGVhbl8xX2FnZ21lZCIsICJ0YXJnZXRfY2xlYW5fMl9hZ2dtZWQiLCAidGFyZ2V0X2NsZWFuXzNfYWdnbWVkIildIDwtCiAgZXZlbnRzWywgYygidGFyZ2V0X2NsZWFuXzFfYWdnbG93IiwgInRhcmdldF9jbGVhbl8yX2FnZ2xvdyIsICJ0YXJnZXRfY2xlYW5fM19hZ2dsb3ciKV0KZXZlbnRzIDwtIGV2ZW50cyAlPiUKICBtdXRhdGVfYXQoCiAgICB2YXJzKHN0YXJ0c193aXRoKCJpbml0aWF0b3JfY2xlYW5fMV9hZ2dtZWR8aW5pdGlhdG9yX2NsZWFuXzJfYWdnbWVkfGluaXRpYXRvcl9jbGVhbl8zX2FnZ21lZCIpKSwKICAgIC5mdW5zID0gZnVucyhjYXI6OnJlY29kZSh0ZW1wLCAiCiAgICAgYygnY2lkJywna2VueWEgcG9saWNlIHJlc2VydmUnLCdrZW55YSBwb2xpY2UnLCdwb2xpY2UgKGdlbmVyaWMpJywncmFpbHdheSBwb2xpY2UnLAonc3BlY2lhbCBicmFuY2gnLCd0cmliYWwgcG9saWNlJywndHJpYmFsIHBvbGljZSByZXNlcnZlJykgPSAncG9saWNlJzsKICAgICBjKCdhcmFiIGNvbWJhdCB1bml0cycsJ2FzaWFuIGNvbWJhdCB1bml0cycsJ2JyaXRpc2ggbWlsaXRhcnknLCdLaW5ncyBBZnJpY2FuIFJpZmxlcycsCidrZW55YSByZWdpbWVudCcsJ21pbGl0YXJ5IChnZW5lcmljKScsJ3BzdWVkbyBnYW5ncycsJ3JveWFsIGFpciBmb3JjZScpID0gJ21pbGl0YXJ5JzsKICAgICBjKCdjb2xvbmlhbCBhdXRob3JpdGllcycsICd0cmliYWwgYXV0aG9yaXRpZXMnKT0nY2l2aWwgYXV0aG9yaXRpZXMnOwogICAgIGMoJ2FtbXVuaXRpb24nLCdmaXJlYXJtcycsJ290aGVyIHdlYXBvbnMnKT0nYXJtYW1lbnRzJzsKICAgICBjKCdjYXNoJywnZm9vZCcsJ2xpdmVzdG9jaycsJ21lZGljaW5lJywnc3VwcGxpZXMnKT0ncHJvdmlzaW9ucyc7CiAgICAgYygnY2h1cmNoJywnc2Nob29sJywnaW5mcmFzdHJ1Y3R1cmUnKT0ncHVibGljIGJ1aWxkaW5ncyc7CiAgICAgICAgICAiKSkKICApCgpldmVudHMkaW5pdGlhdG9yX2NsZWFuXzFfYWdnbWVkICU+JQogIHRhYnlsKHNvcnQgPSBUUlVFKSAlPiUKICBhZG9ybl9jcm9zc3RhYihkaWdpdHMgPSAxKQpgYGAKCmBgYHtyIENvbGxhcHNlIEV2ZW50IEluaXRhdG9ycyAsY2FjaGU9VH0KCmV2ZW50c1ssIGMoInRhcmdldF9jbGVhbl8xX2FnZ2hpZ2giLCAidGFyZ2V0X2NsZWFuXzJfYWdnaGlnaCIsICJ0YXJnZXRfY2xlYW5fM19hZ2doaWdoIildIDwtCiAgZXZlbnRzWywgYygidGFyZ2V0X2NsZWFuXzFfYWdnbWVkIiwgInRhcmdldF9jbGVhbl8yX2FnZ21lZCIsICJ0YXJnZXRfY2xlYW5fM19hZ2dtZWQiKV0KZXZlbnRzIDwtIGV2ZW50cyAlPiUKICBtdXRhdGVfYXQoCiAgICB2YXJzKHN0YXJ0c193aXRoKCJ0YXJnZXRfY2xlYW5fMV9hZ2doaWdofHRhcmdldF9jbGVhbl8yX2FnZ2hpZ2h8dGFyZ2V0X2NsZWFuXzNfYWdnaGlnaCIpKSwKICAgIC5mdW5zID0gZnVucyhjYXI6OnJlY29kZSgiCiAgICAgICAgICAgICAgICAgIGMoJ2NpdmlsIGF1dGhvcml0aWVzJywgJ2hvbWUgZ3VhcmQnLCAnbWlsaXRhcnknLCAncG9saWNlJywgJ3BhcmFtaWxpdGFyeScpID0nZ292ZXJubWVudCc7CiAgICAgICAgICAgICAgICAgIGMoJ3N1c3BlY3RlZCBpbnN1cmdlbnRzJywnZGV0YWluZWVzJykgPSdyZWJlbHMnOwogICAgICAgICAgICAgICAgICBjKCdhcm1hbWVudHMnLCdwcml2YXRlIHByb3BlcnR5JywncHJvdmlzaW9ucycsJ3B1YmxpYyBidWlsZGluZ3MnKSA9J3Byb3BlcnR5JzsKICAgICAgICAgICAgICAgICAgYygnY29tbXVuaXRpZXMnLCdjb21tdW5pdGllcycpPSdjaXZpbGlhbnMnOwogICAgICAgICAgIikpCiAgKQoKZXZlbnRzJHRhcmdldF9jbGVhbl8xX2FnZ2hpZ2ggJT4lCiAgdGFieWwoc29ydCA9IFRSVUUpICU+JQogIGFkb3JuX2Nyb3NzdGFiKGRpZ2l0cyA9IDEpCmBgYAoKCgojIyBDb3VudCBvZiBJbml0aWF0b3JzCgpIZWxwZXIgZnVuY3Rpb24gZm9yIHJlY29kaW5nCgpgYGB7ciBSZWNvZGUgSGVscGVyIEZVbmN0aW9uLCByZXN1bHRzPSJhc2lzIn0KCnJlY29kZXJGdW5jIDwtIGZ1bmN0aW9uKGRhdGEsIG9sZHZhbHVlLCBuZXd2YWx1ZSkgewogICMgY29udmVydCBhbnkgZmFjdG9ycyB0byBjaGFyYWN0ZXJzCiAgaWYgKGlzLmZhY3RvcihkYXRhKSkgZGF0YSA8LSBhcy5jaGFyYWN0ZXIoZGF0YSkKICBpZiAoaXMuZmFjdG9yKG9sZHZhbHVlKSkgb2xkdmFsdWUgPC0gYXMuY2hhcmFjdGVyKG9sZHZhbHVlKQogIGlmIChpcy5mYWN0b3IobmV3dmFsdWUpKSBuZXd2YWx1ZSA8LSBhcy5jaGFyYWN0ZXIobmV3dmFsdWUpCgogICMgY3JlYXRlIHRoZSByZXR1cm4gdmVjdG9yCiAgbmV3dmVjIDwtIGRhdGEKICAjIHB1dCByZWNvZGVkIHZhbHVlcyBpbnRvIHRoZSBjb3JyZWN0IHBvc2l0aW9uIGluIHRoZSByZXR1cm4gdmVjdG9yCiAgZm9yIChpIGluIHVuaXF1ZShvbGR2YWx1ZSkpIG5ld3ZlY1tkYXRhICVpbiUgaV0gPC0gbmV3dmFsdWVbb2xkdmFsdWUgJWluJSBpXQogIG5ld3ZlYwp9CmBgYAoKYGBge3IgQ291bnQgb2YgSW5pdGlhdG9yc30KCiMgVGhlc2UgbnVtYmVycyBhcmUgaW1wcm92aXNlZCBhbmQgY2FuIGJlIGNoYW5nZWQKYWNvdXBsZSA8LSAyCmFmZXcgPC0gMwphZ2FuZyA8LSA2CmFnYW5nX2xhcmdlIDwtIDEyCgpyZWNvZGluZ3MgPC0gYygKICAiMTAwKyIsICIxMDAiLAogICI/PyIsICIiLAogICIxIGJhZyIsICIxIiwKICAiMSBibGFua2V0IiwgIjEiLAogICIxIGJ1cm50IGRvd24iLCAiMSIsCiAgIjEgY2l2aWxpYW4iLCAiMSIsCiAgIjEgY293LCA2IHNoZWVwIiwgIjciLAogICIxIGNvdyIsICIxIiwKICAiMSBnb2F0LCBjbG90aGluZyIsICIxIiwKICAiMSBnb2F0IiwgIjEiLAogICIxIGxvb3RlZCIsICIxIiwKICAiMSBsb290ZWQiLCAiMSIsCiAgIjEgb3giLCAiMSIsCiAgIjEgc2hlZXAgYW5kIGNoaWNrZW5zIiwgIjEiLAogICIxIHNoZWVwLCBzb21lIGNoaWNrZW5zIiwgIjEiLAogICIxIHNoZWVwIiwgIjEiLAogICIxIHNob3RndW4gLDMwIHJvdW5kcyIsICIzMSIsCiAgIjEgc2hvdGd1biArIDEwcmRzIiwgIjExIiwKICAiMSBzdGVlciIsICIxIiwKICAiMSB2aWxsYWdlLCAxIG1hcmtldCIsICIxIiwKICAiMSB3b3VuZGVkIiwgIjEiLAogICIxIHdyZWNrZWQiLCAiMSIsCiAgIjErIiwgIjEiLAogICIxKzMiLCAiNCIsCiAgIjErc29tZSIsICIxIiwKICAiMTAgYWNyZXMiLCAiMTAiLAogICIxMCBiYWdzIiwgIjEwIiwKICAiMTAgY2F0dGxlIiwgIjEwIiwKICAiMTAgc2Fja3MiLCAiMTAiLAogICIxMCB0byAxMiIsICIxMSIsCiAgIjEwIHRvIDE1IiwgIjEzIiwKICAiMTAvMTQvMjAxMyIsICIiLAogICIxMC8xNS8yMDEzIiwgIiIsCiAgIjEwLzIwLzIwMTMiLCAiIiwKICAiMTAwIGxiIiwgIjEwMCIsCiAgIjEwMC0xMzAiLCAiMTE1IiwKICAiMTAwLTE1MCIsICIxMjUiLAogICIxMDArIiwgMTAwLAogICIxMDAwMCIsICIiLAogICIxMDkgY2F0dGxlIiwgIjEwOSIsCiAgIjEwYmFncyBwb3RhdG9lcyIsICIxMCIsCiAgIjExIGNhdHRsZSIsICIxMSIsCiAgIjExIHNoZWVwIiwgIjExIiwKICAiMTEyIGJvcmUgJiAyMC4xLjQ1ICY3IHJkcyIsICIxMTIiLAogICIxMiBiYWdzIiwgIjEyIiwKICAiMTIgY2F0dGxlIiwgIjEyIiwKICAiMTIgZ29hdHMiLCAiMTIiLAogICIxMiB0byAxNSIsICIxMyIsCiAgIjEyIHRvIDIwIiwgIjE3IiwKICAiMTIvMTQvMjAxMyIsICIiLAogICIxMjAgY2F0dGxlIiwgIjEyMCIsCiAgIjEyMCsxIiwgIjEyMSIsCiAgIjEzIHNoZWVwIiwgIjEzIiwKICAiMTMtMTUiLCAiMTQiLAogICIxMzAwIHdvcnRoIiwgIjEzMDAiLAogICIxNCBjYXR0bGUiLCAiMTQiLAogICIxNCBnb2F0cyIsICIxNCIsCiAgIjE0IGhlYWQiLCAiMTQiLAogICIxNCsiLCAiMTQiLAogICIxNSAtIDIwIiwgIjE4IiwKICAiMTUgY2F0dGxlIiwgIjE1IiwKICAiMTUgdG8gMjAiLCAiMTciLAogICIxNSB0byAyMCIsICIxNyIsCiAgIjE1IHRvIDI1IiwgIjIwIiwKICAiMTUtMjAiLCAiMTciLAogICIxNSsiLCAiMTUiLAogICIxNTAtMjAwIiwgIjE3NSIsCiAgIjE1MCsiLCAiMTUwIiwKICAiMTUxIGNhdHRsZSIsICIxNTEiLAogICIxNyBjYXR0bGUiLCAiMTciLAogICIxNzIgYmFncyBidXJudCIsICIxNzIiLAogICIxOCBjYXR0bGUiLCAiMTgiLAogICIxOSBiYWdzIiwgIjE5IiwKICAiMTk2IHJvdW5kcyIsICIxOTYiLAogICIyIGJhZ3MgbWFpemUiLCAiMiIsCiAgIjIgYmFncyIsICIyIiwKICAiMiBiYWdzIiwgIjIiLAogICIyIGJ1Y2tldHMiLCAiMiIsCiAgIjIgY2F0dGxlIGhhbXN0cnVuZyIsICIyIiwKICAiMiBjYXR0bGUsIGNvcm4iLCAiMyIsCiAgIjIgY2F0dGxlIiwgIjIiLAogICIyIGNvd3MiLCAiMiIsCiAgIjIgZGViYmllcyIsICIyIiwKICAiMiBnb2F0cyIsICIyIiwKICAiMiBncm91cHMiLCAiMiIsCiAgIjIgaHV0cyBidXJudCIsICIyIiwKICAiMiBzaGVlcCIsICIyIiwKICAiMiB3YXRjaGVzLCBjYXNoIiwgIjIiLAogICIyLzMvMjAxMyIsICIiLAogICIyKyIsICIyIiwKICAiMjAgYmFncyBtYWl6ZSwgOSBnb2F0cywgMzIgY2hpY2tlbnMgYW5kIGR1Y2tzLCBjYXNoIiwgIjYwIiwKICAiMjAgYmFncyIsICIyMCIsCiAgIjIwIGNhdHRsZSIsICIyMCIsCiAgIjIwIGdvYXRzIiwgIjIwIiwKICAiMjAgc2hlZXAiLCAiMjAiLAogICIyMCB0byAyNSIsICIyMyIsCiAgIjIwIHRvIDMwIiwgIjI1IiwKICAiMjAgdG8gNDAiLCAiMzAiLAogICIyMC0yNSIsICIyMyIsCiAgIjIwLTMwIiwgIjI1IiwKICAiMjAtMzUiLCAiMzAiLAogICIyMC01MCIsICIzNSIsCiAgIjIwLzMwIiwgIjI1IiwKICAiMjAvMzAiLCAiMjUiLAogICIyMCsiLCAiMjAiLAogICIyMDAgeWRzIiwgIjIwMCIsCiAgIjIwMC0zMDAiLCAiMjUwIiwKICAiMjAwKyIsICIyMDAiLAogICIyMDAwIGFjcmVzIiwgIjIwMDAiLAogICIyMSBnb2F0cyIsICIyMSIsCiAgIjIxIGhlYWQiLCAiMjEiLAogICIyMiBjYXR0bGUiLCAiMjIiLAogICIyNSB0byAzMCIsICIyOCIsCiAgIjI1LTMwIiwgIjI3IiwKICAiMjUtMzAiLCAiMjciLAogICIyOCBraWxsZWQiLCAiMjgiLAogICIyOCBzaGVlcCIsICIyOCIsCiAgIjMgYmFncyIsICIzIiwKICAiMyBiYWdzIiwgIjMiLAogICIzIGJpa2VzIiwgIjMiLAogICIzIGNhdHRsZSIsICIzIiwKICAiMyBjYXR0bGUiLCAiMyIsCiAgIjMgZ29hdHMiLCAiMyIsCiAgIjMgb3IgNCIsICIzIiwKICAiMyBvciA0IiwgIjMiLAogICIzIHBhbmdhcyIsICIzIiwKICAiMyBzaGVlcCwgMiBjYWx2ZXMiLCAiNSIsCiAgIjMgc2hlZXAiLCAiMyIsCiAgIjMgdG8gNCIsICIzIiwKICAiMyB0byA0IiwgIjMiLAogICIzLzEwLzIwMTMiLCAiIiwKICAiMy80LzIwMTMiLCAiIiwKICAiMy81LzIwMTMiLCAiIiwKICAiMy82LzIwMTMiLCAiIiwKICAiMysiLCAiMyIsCiAgIjMrMysxKzIiLCAiOSIsCiAgIjMrc29tZSIsICIzIiwKICAiMzAgYWNyZXMiLCAiMzAiLAogICIzMCBjYXR0bGUiLCAiMzAiLAogICIzMCB0byA0MCIsICIzNSIsCiAgIjMwLTM1IiwgIjMzIiwKICAiMzAtNDAiLCAiMzUiLAogICIzMC01MCIsICI0MCIsCiAgIjMwKyIsICIzMCIsCiAgIjMwMC00MDAiLCAiMzUwIiwKICAiMzAwKyIsICIzMDAiLAogICIzNSBiYWdzIiwgIjM1IiwKICAiMzUgdG8gNDAiLCAiMzciLAogICIzOCBjYXR0bGUiLCAiMzgiLAogICIzb3IgNCIsICIzIiwKICAiNCBiYWdzIHBvdGF0b2VzIiwgIjQiLAogICI0IGJhZ3MiLCAiNCIsCiAgIjQgZ29hdHMiLCAiNCIsCiAgIjQgZ3JvdXBzIiwgIiIsCiAgIjQgb3IgNSIsICI0IiwKICAiNCBveGVuIiwgIjQiLAogICI0IHNoZWVwIiwgIjQiLAogICI0IHRvIDgiLCAiNiIsCiAgIjQvNi8yMDEzIiwgIiIsCiAgIjQwIGJhZyIsICI0MCIsCiAgIjQwIGNhdHRsZSIsICI0MCIsCiAgIjQwIHNhY2tzIiwgIjQwIiwKICAiNDAgc2hlZXAiLCAiNDAiLAogICI0MCB0byA1MCIsICI0NSIsCiAgIjQwLzUwIiwgIjQ1IiwKICAiNDAwIGNhdHRsZSIsICI0MDAiLAogICI0MDAwIiwgIiIsCiAgIjQ0IGNhdHRsZSIsICI0NCIsCiAgIjUgYmFncyIsICI1IiwKICAiNSBjYWx2ZXMiLCAiNSIsCiAgIjUgY2F0dGxlIiwgIjUiLAogICI1IGRlc3Ryb3llZCIsICI1IiwKICAiNSBnb2F0cyIsICI1IiwKICAiNSBraWxsZWQiLCAiNSIsCiAgIjUgb3IgNiIsICI1IiwKICAiNSBzaGVlcCwgMSBveCIsICI2IiwKICAiNSBzaGVlcCIsICI1IiwKICAiNSB0byA2IiwgIjUiLAogICI1LzEwLzIwMTMiLCAiIiwKICAiNS82LzIwMTMiLCAiIiwKICAiNTAgY2F0dGxlIiwgIjUwIiwKICAiNTAgdG8gNjAiLCAiNTUiLAogICI1MC0xMDAiLCAiNzUiLAogICI1MC02MCIsICI1NSIsCiAgIjUwLTc1IiwgIjYyIiwKICAiNTArIiwgIjUwIiwKICAiNTArIiwgIjUwIiwKICAiNTAwMCBhY3JlcyIsICI1MDAwIiwKICAiNTE5ICsiLCAiNTE5IiwKICAiNTMgZGV0YWluZWQiLCAiNTMiLAogICI1NCBzaGVlcCBhbmQgZ29hdHMiLCAiNTQiLAogICI1NiBjb21taXR0ZWUgbWVtYmVycyIsICI1NiIsCiAgIjYgYmFnIiwgIjYiLAogICI2IGJhZ3MiLCAiNiIsCiAgIjYgY2F0dGxlIiwgIjYiLAogICI2IGNhdHRsZSIsICI2IiwKICAiNiBnb2F0cyIsICI2IiwKICAiNiBvciA3IiwgIjYiLAogICI2IHNoZWVwIGFuZCBnb2F0cyIsICI2IiwKICAiNiBzaGVlcCIsICI2IiwKICAiNiB0byA3IiwgIjYiLAogICI2IHRvIDgiLCAiNyIsCiAgIjYgdG8gOSIsICI4IiwKICAiNi04IG1hbiIsICI3IiwKICAiNi8xMC8yMDEzIiwgIiIsCiAgIjYvOC8yMDEzIiwgIiIsCiAgIjYwLTEwMCIsICI4MCIsCiAgIjYwLTcwIiwgIjY1IiwKICAiNjQgY2F0dGxlIiwgIjY0IiwKICAiNyBiYWdzIiwgIjciLAogICI3IGNhdHRsZSIsICI3IiwKICAiNyBzaGVlcCIsICI3IiwKICAiNy8xMC8yMDEzIiwgIiIsCiAgIjcwIGJhZ3MiLCAiNzAiLAogICI3MCBjYXR0bGUsIHNoZWVwIiwgIjcwIiwKICAiNzAtMTAwIiwgIjg1IiwKICAiNzAwMDAiLCAiIiwKICAiNzUgcm91bmRzIiwgIjc1IiwKICAiOCBiYWdzIHBvdGF0b2VzIiwgIjgiLAogICI4IGNhdHRsZSIsICI4IiwKICAiOCBjb3dzIHNsYXNoZWQiLCAiOCIsCiAgIjggY293cyIsICI4IiwKICAiOCBzaGVlcCIsICI4IiwKICAiOCB0byAxMCIsICI5IiwKICAiOC8xMC8yMDEzIiwgIiIsCiAgIjgwIGNhdHRsZSIsICI4MCIsCiAgIjgwLTEwMCIsICI5MCIsCiAgIjg0IHNoZWVwLCAxIGNvdywgNSBjaGlja2VucyIsICI5MCIsCiAgIjkgY2F0dGxlIiwgIjkiLAogICI5IHNoZWVwIiwgIjkiLAogICI5IHRvIDEwIiwgIjkiLAogICI5KzkiLCAiMTgiLAogICI5MDAobm90IGNsZWFyKSIsICI5MDAiLAogICJhbGwgbG9jYWxzIiwgIiIsCiAgImFsbCIsICIiLAogICJhcHAgNSIsICI1IiwKICAiYXBwLiAxMDAiLCAiMTAwIiwKICAiYXBwLiAxMjAiLCAiMTIwIiwKICAiYXJtZWQgZ2FuZyIsIGFnYW5nLAogICJiYW5kIiwgYWdhbmcsCiAgImJhbmRzIiwgIiIsCiAgImNhdHRsZSBzbGFzaGluZyIsICIiLAogICJjbG90aGluZyIsICIiLAogICJjb25zaWRlcmFibGUgcXVhbnRpdHkiLCAiIiwKICAiZmFpcmx5IGxhcmdlIGdhbmciLCBhZ2FuZ19sYXJnZSwKICAiZmV3IGJhZ3MiLCAiIiwKICAiZmV3IiwgIiIsCiAgImZvb2QiLCAiIiwKICAiZ2FuZyIsIGFnYW5nLAogICJnYW5ncyIsIGFnYW5nX2xhcmdlLAogICJndWFyZHMiLCBhZmV3LAogICJoYWxmIHZpbGxhZ2UiLCAiIiwKICAibGFib3VyIiwgIiIsCiAgImxhcmdlIGNyb3dkIiwgIiIsCiAgImxhcmdlIGZvcmNlIiwgYWdhbmdfbGFyZ2UsCiAgImxhcmdlIGdhbmciLCBhZ2FuZ19sYXJnZSwKICAibGFyZ2UgbWVldGluZyIsICIiLAogICJsYXJnZSBudW1iZXIiLCAiIiwKICAibGFyZ2UgbnVtYmVycyIsICIiLAogICJsYXJnZSBxdWFudGl0aWVzIiwgIiIsCiAgImxhcmdlIHF1YW50aXR5IiwgIiIsCiAgImxhcmdlIHJlLW9hdGhpbmcgY2VyZW1vbnkiLCAiIiwKICAibGFyZ2Ugc2NhbGUiLCAiIiwKICAibGFyZ2UiLCBhZ2FuZ19sYXJnZSwKICAibGFyZ2lzaCBnYW5nIiwgYWdhbmdfbGFyZ2UsCiAgImxvY2FsIHBvcHVsYWNlIiwgIiIsCiAgIm1hbnkgdGhvdXNhbmQiLCAiMjAwMCIsCiAgIm1vYiIsICIiLAogICJub3QgZ2l2ZW4iLCAiIiwKICAibnVtYmVyIiwgIiIsCiAgIm9jY3VwYW50cyIsICIiLAogICJvdmVyIDIwMCIsICIyMDAiLAogICJwYXJ0eSIsICIiLAogICJwYXJ0eSIsIGFnYW5nLAogICJwYXRyb2wiLCBhZ2FuZywKICAicG9zaG8iLCAiIiwKICAicG90YXRvZXMiLCAiIiwKICAicXVhbnRpdHkgb2YgY2xvdGhpbmciLCAiIiwKICAic2VjdGlvbiIsICIiLAogICJzZXZlcmFsIGdhbmdzIiwgImFnYW5nX2xhcmdlIiwKICAic2V2ZXJhbCIsICIzIiwKICAic2hlZXAgYW5kIGdvYXRzIiwgIiIsCiAgInNocyAyLDMwMC8tIiwgIjIzMDAiLAogICJzaHMgNjAvLSIsICI2MCIsCiAgInNocy4gMSwwMDAiLCAiMTAwMCIsCiAgInNocy4gMTgiLCAiMTgiLAogICJzaHMuIDMwIiwgIjMwIiwKICAic21hbGwgZ2FuZyIsIGFnYW5nLAogICJzbWFsbCBnYW5ncyIsICJhZ2FuZyIsCiAgInNtYWxsIGdyb3VwIiwgYWdhbmcsCiAgInNtYWxsIHBhcnR5IiwgYWZldywKICAic21hbGwiLCBhZ2FuZywKICAic29tZSIsIGFmZXcsCiAgInN1ZmZpY2llbnQgZm9vZCIsICIiLAogICJ1bmtub3duIiwgIiIsCiAgInZlcnkgbGFyZ2UgZ2FuZyIsICJhZ2FuZ19sYXJnZSIsCiAgInZpbGxhZ2VzIGluIG5kaWEsIGdpY2h1Z3UsIGVtYnUgZGl2aXNpb25zIiwgIiIsCiAgIndpdmVzIiwgIiIKKQpyZWNvZGluZ3MgPC0gbWF0cml4KHJlY29kaW5ncywgbmNvbCA9IDIsIGJ5cm93ID0gVCkKCmV2ZW50cyRpbml0aWF0b3JfbnVtYmVyc19udW1lcmljIDwtIGV2ZW50cyRpbml0aWF0b3JfbnVtYmVycyAlPiUgcmVjb2RlckZ1bmMoLiwgcmVjb2RpbmdzWywgMV0sIHJlY29kaW5nc1ssIDJdKSAlPiUgYXMubnVtZXJpYygpCmV2ZW50cyR0YXJnZXRfbnVtYmVyc19udW1lcmljIDwtIGV2ZW50cyR0YXJnZXRfbnVtYmVycyAlPiUgcmVjb2RlckZ1bmMoLiwgcmVjb2RpbmdzWywgMV0sIHJlY29kaW5nc1ssIDJdKSAlPiUgYXMubnVtZXJpYygpCmV2ZW50cyRhZmZlY3RlZF9jb3VudF9udW1lcmljIDwtIGV2ZW50cyRhZmZlY3RlZF9jb3VudCAlPiUgcmVjb2RlckZ1bmMoLiwgcmVjb2RpbmdzWywgMV0sIHJlY29kaW5nc1ssIDJdKSAlPiUgYXMubnVtZXJpYygpCmBgYAoKIyBDYXN1YWx0aWVzCgpgYGB7ciBDYXN1YWx0aWVzLCByZXN1bHRzPSJhc2lzIn0KCmV2ZW50c1ssIGMoCiAgImdvdmVybm1lbnRfa2lsbGVkX2NsZWFuIiwgImdvdmVybm1lbnRfd291bmRlZF9jbGVhbiIsICJnb3Zlcm5tZW50X2NhcHR1cmVkX2NsZWFuIiwKICAicmViZWxzX2tpbGxlZF9jbGVhbiIsICJyZWJlbHNfd291bmRlZF9jbGVhbiIsICJyZWJlbHNfY2FwdHVyZWRfY2xlYW4iLAogICJjaXZpbGlhbnNfa2lsbGVkX2NsZWFuIiwgImNpdmlsaWFuc193b3VuZGVkX2NsZWFuIiwgImNpdmlsaWFuc19jYXB0dXJlZF9jbGVhbiIKKV0gPC0KICBldmVudHNbLCBjKAogICAgImdvdmVybm1lbnRfa2lsbGVkIiwgImdvdmVybm1lbnRfd291bmRlZCIsICJnb3Zlcm5tZW50X2NhcHR1cmVkIiwKICAgICJyZWJlbHNfa2lsbGVkIiwgInJlYmVsc193b3VuZGVkIiwgInJlYmVsc19jYXB0dXJlZCIsCiAgICAiY2l2aWxpYW5zX2tpbGxlZCIsICJjaXZpbGlhbnNfd291bmRlZCIsICJjaXZpbGlhbnNfY2FwdHVyZWQiCiAgKV0KCmV2ZW50cyA8LSBldmVudHMgJT4lIG11dGF0ZV9hdCgKICAudmFycyA9IGMoCiAgICAiZ292ZXJubWVudF9raWxsZWRfY2xlYW4iLCAiZ292ZXJubWVudF93b3VuZGVkX2NsZWFuIiwgImdvdmVybm1lbnRfY2FwdHVyZWRfY2xlYW4iLAogICAgInJlYmVsc19raWxsZWRfY2xlYW4iLCAicmViZWxzX3dvdW5kZWRfY2xlYW4iLCAicmViZWxzX2NhcHR1cmVkX2NsZWFuIiwKICAgICJjaXZpbGlhbnNfa2lsbGVkX2NsZWFuIiwgImNpdmlsaWFuc193b3VuZGVkX2NsZWFuIiwgImNpdmlsaWFuc19jYXB0dXJlZF9jbGVhbiIKICApLAogIGZ1bnMoYXMubnVtZXJpYyhjYXI6OnJlY29kZSguLCAiICdGZXcnPScyJzsnTWFueSc9JzMnOydvdGhlcnMnPScyJzsnU2V2YXJhbCc9JzMnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NldmVyYWwnPSczJzsgJ1NldmVyYWwgTW9yZSc9JzMnOyAnU2V2ZXJhbCBvdGhlcnMnPSczJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnU29tZSc9JzMnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcxMDArJz0nMTAwJzsgJzIzIEZhbWlsaWVzJz0nMjMnOyAnMjggZmFtaWxpZXMnPScyOCc7ICczMC00MCc9JzM1JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnNTArJz0nNTAnOyAnQ291bmNpbCBvZiBlbGRlcnMnPSczJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDb3VuY2lsIG9mIHdhcic9JzMnOyAnRmV3Jz0nMic7ICdzb21lJz0nMic7IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTZXZlcmFsJz0nMyc7ICAnNDUwMCc9JzQ1JzsgJzgwMCc9JzgwJzsgJ0dhbmcnPSczJzsgJ01ham9yaXR5Jz0nMyc7IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA7ICdtYW55Jz0nMycgIDsgJ1NldmVyYWwnPSczJyA7ICdTbWFsbCBnYW5nJz0nMycgOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzYrJz0nNicgOyAnMTArJz0nMTAnIDsgJzMrJz0nMyc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd1bktub3duJz0nMSc7ICd1bmtub3duJz0nMSc7ICdVbktub3duJz0nMSc7ICAnVU5LTk9XTic9JzEnOyAnVW5rb3duJz0nMSc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdVbmtub3duJz0nMScgOyAnTnVtYmVyJz0nMSc7J01vcmUnPScxJzsgJzEwMTk3Jz0nJyA7ICcxMDEnPScxJyA7Cic0OCc9JzcnIDsgJzE0Nic9JzEnIDsgJzEyMic9JzEnOyAgJzIwOCc9JzEnOyAnOTQnPScxJyA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BPTAiKSkpCikKCmV2ZW50cyA8LSBldmVudHMgJT4lIG11dGF0ZV9hdCgudmFycyA9IGMoCiAgImdvdmVybm1lbnRfa2lsbGVkX2NsZWFuIiwgImdvdmVybm1lbnRfd291bmRlZF9jbGVhbiIsICJnb3Zlcm5tZW50X2NhcHR1cmVkX2NsZWFuIiwKICAicmViZWxzX2tpbGxlZF9jbGVhbiIsICJyZWJlbHNfd291bmRlZF9jbGVhbiIsICJyZWJlbHNfY2FwdHVyZWRfY2xlYW4iLAogICJjaXZpbGlhbnNfa2lsbGVkX2NsZWFuIiwgImNpdmlsaWFuc193b3VuZGVkX2NsZWFuIiwgImNpdmlsaWFuc19jYXB0dXJlZF9jbGVhbiIKKSwgZnVucyhhcy5udW1lcmljKSkKCmV2ZW50cyA8LSBldmVudHMgJT4lCiAgbXV0YXRlKHJlYmVsc19raWxsZWR3b3VuZGVkX2NsZWFuID0gcmViZWxzX2tpbGxlZF9jbGVhbiArIHJlYmVsc193b3VuZGVkX2NsZWFuKSAlPiUKICBtdXRhdGUoZ292ZXJubWVudF9raWxsZWRfd291bmRlZF9jbGVhbiA9IGdvdmVybm1lbnRfa2lsbGVkX2NsZWFuICsgZ292ZXJubWVudF93b3VuZGVkX2NsZWFuKSAlPiUKICBtdXRhdGUocmViZWxzX2dvdmVybm1lbnRfa2lsbGVkd291bmRlZF9jbGVhbiA9IHJlYmVsc19raWxsZWRfY2xlYW4gKyByZWJlbHNfd291bmRlZF9jbGVhbikgJT4lCiAgbXV0YXRlKHJlYmVsc19nb3Zlcm5tZW50X2tpbGxlZF9jbGVhbiA9IHJlYmVsc19raWxsZWRfY2xlYW4gKyBnb3Zlcm5tZW50X2tpbGxlZF9jbGVhbikgJT4lCiAgbXV0YXRlKHJlYmVsc19nb3Zlcm5tZW50X2NpdmlsaWFuc19raWxsZWRfY2xlYW4gPSByZWJlbHNfa2lsbGVkX2NsZWFuICsgZ292ZXJubWVudF9raWxsZWRfY2xlYW4gKyBjaXZpbGlhbnNfa2lsbGVkX2NsZWFuKQpgYGAKCmBgYHtyIENvbGxhcHNlIEV2ZW50IFR5cGVzLGNhY2hlPVR9CgpldmVudHMgJT4lIGNyb3NzdGFiKGluaXRpYXRvcl9jbGVhbl8xX2FnZ2hpZ2gsIHR5cGVfY2xlYW5fYWdnaGlnaCkgJT4lIGFkb3JuX2Nyb3NzdGFiKGRpZ2l0cyA9IDEpCmV2ZW50cyAlPiUgY3Jvc3N0YWIodGFyZ2V0X2NsZWFuXzFfYWdnaGlnaCwgdHlwZV9jbGVhbl9hZ2doaWdoKSAlPiUgYWRvcm5fY3Jvc3N0YWIoZGlnaXRzID0gMSkKZXZlbnRzICU+JSBjcm9zc3RhYih0YXJnZXRfY2xlYW5fMV9hZ2doaWdoLCBpbml0aWF0b3JfY2xlYW5fMV9hZ2doaWdoKSAlPiUgYWRvcm5fY3Jvc3N0YWIoZGlnaXRzID0gMSkKYGBgCgoKIyBPdXRwdXQgQ2xlYW5lZCBGaWxlCgpgYGB7cn0Kc2F2ZVJEUyhldmVudHMsICIvaG9tZS9yZXhkb3VnbGFzcy9Ecm9wYm94IChyZXgpL0tlbnlhIEFydGljbGUgRHJhZnRzL01lYXN1cmluZ0xhbmRzY2FwZUNpdmlsV2FyL2luc3QvZXh0ZGF0YS9NZWFzdXJpbmdMYW5kc2NhcGVDaXZpbFdhcl9ldmVudHNfY2xlYW5lZC5SZGF0YSIpCgpgYGAKCg==